1 package org.apache.maven.scm.provider.bazaar.command.diff;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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.apache.maven.scm.provider.bazaar.command.BazaarConsumer;
26
27 import java.io.File;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32
33
34
35
36
37 public class BazaarDiffConsumer
38 extends BazaarConsumer
39 {
40
41 private static final String MODIFIED_FILE_TOKEN = "=== modified file ";
42
43 private static final String ADDED_FILE_TOKEN = "=== added file ";
44
45 private static final String DELETED_FILE_TOKEN = "=== deleted file ";
46
47 private static final String NO_NEWLINE_TOKEN = "\\ No newline at end of file";
48
49 private static final String FROM_FILE_TOKEN = "---";
50
51 private static final String TO_FILE_TOKEN = "+++";
52
53 private static final String ADDED_LINE_TOKEN = "+";
54
55 private static final String REMOVED_LINE_TOKEN = "-";
56
57 private static final String UNCHANGED_LINE_TOKEN = " ";
58
59 private static final String RANGE_TOKEN = "@@";
60
61 private ScmLogger logger;
62
63 private File workingDirectory;
64
65 private String currentFile;
66
67 private StringBuilder currentDifference;
68
69 private List<ScmFile> changedFiles = new ArrayList<ScmFile>();
70
71 private Map<String, CharSequence> differences = new HashMap<String, CharSequence>();
72
73 private StringBuilder patch = new StringBuilder();
74
75 public BazaarDiffConsumer( ScmLogger logger, File workingDirectory )
76 {
77 super( logger );
78 this.logger = logger;
79 this.workingDirectory = workingDirectory;
80 }
81
82
83 public void doConsume( ScmFileStatus status, String line )
84 {
85 String tmpLine = new String( line );
86 patch.append( line ).append( "\n" );
87
88
89 if ( line.startsWith( MODIFIED_FILE_TOKEN ) )
90 {
91 tmpLine = line.substring( MODIFIED_FILE_TOKEN.length() );
92 tmpLine = tmpLine.trim();
93 status = ScmFileStatus.MODIFIED;
94 addChangedFile( status, line, tmpLine );
95 }
96 else if ( line.startsWith( ADDED_FILE_TOKEN ) )
97 {
98 tmpLine = line.substring( ADDED_FILE_TOKEN.length() );
99 tmpLine = tmpLine.trim();
100 status = ScmFileStatus.ADDED;
101 addChangedFile( status, line, tmpLine );
102 }
103 else if ( line.startsWith( DELETED_FILE_TOKEN ) )
104 {
105 tmpLine = line.substring( DELETED_FILE_TOKEN.length() );
106 tmpLine = tmpLine.trim();
107 status = ScmFileStatus.DELETED;
108 addChangedFile( status, line, tmpLine );
109 }
110 else if ( line.startsWith( TO_FILE_TOKEN ) || line.startsWith( FROM_FILE_TOKEN ) )
111 {
112
113 }
114 else if ( line.startsWith( ADDED_LINE_TOKEN ) || line.startsWith( REMOVED_LINE_TOKEN )
115 || line.startsWith( UNCHANGED_LINE_TOKEN ) || line.startsWith( RANGE_TOKEN )
116 || line.startsWith( NO_NEWLINE_TOKEN ) )
117 {
118 currentDifference.append( line ).append( "\n" );
119 }
120 }
121
122
123
124
125
126
127
128
129
130
131 private void addChangedFile( ScmFileStatus status, String line, String tmpLine )
132 {
133 tmpLine = tmpLine.substring( 1, tmpLine.length() - 1 );
134 boolean ok = addChangedFile( status, tmpLine );
135
136 if ( !ok )
137 {
138 int index = tmpLine.indexOf( '/' );
139 if ( index > -1 )
140 {
141 tmpLine = tmpLine.substring( index + 1 );
142 ok = addChangedFile( status, tmpLine );
143 }
144 }
145
146 if ( !ok )
147 {
148 if ( logger.isWarnEnabled() )
149 {
150 logger.warn( "Could not figure out of line: " + line );
151 }
152 }
153 }
154
155
156
157
158
159
160 private boolean addChangedFile( ScmFileStatus status, String tmpLine )
161 {
162 File tmpFile = new File( workingDirectory, tmpLine );
163 if ( status.equals( ScmFileStatus.DELETED ) )
164 {
165 return true;
166 }
167
168 if ( tmpFile.isFile() )
169 {
170 currentFile = tmpLine;
171 currentDifference = new StringBuilder();
172 differences.put( currentFile, currentDifference );
173 changedFiles.add( new ScmFile( tmpLine, status ) );
174 return true;
175 }
176
177 return false;
178 }
179
180 public List<ScmFile> getChangedFiles()
181 {
182 return changedFiles;
183 }
184
185 public Map<String, CharSequence> getDifferences()
186 {
187 return differences;
188 }
189
190 public String getPatch()
191 {
192 return patch.toString();
193 }
194 }