1 package org.apache.maven.scm.provider.perforce.command.changelog;
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.ChangeFile;
23 import org.apache.maven.scm.ChangeSet;
24 import org.apache.maven.scm.ScmException;
25 import org.apache.maven.scm.log.ScmLogger;
26 import org.apache.maven.scm.util.AbstractConsumer;
27
28 import java.util.ArrayList;
29 import java.util.Date;
30 import java.util.LinkedHashMap;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35
36
37
38
39
40 public class PerforceChangeLogConsumer
41 extends AbstractConsumer
42 {
43
44
45
46 private static final String PERFORCE_TIMESTAMP_PATTERN = "yyyy/MM/dd HH:mm:ss";
47
48 private List<ChangeSet> entries = new ArrayList<ChangeSet>();
49
50
51
52
53 private static final int GET_REVISION = 1;
54
55
56
57
58 private static final int GET_COMMENT_BEGIN = 2;
59
60
61
62
63 private static final int GET_COMMENT = 3;
64
65
66
67
68 private static final String COMMENT_DELIMITER = "";
69
70
71
72
73 private static final String FILE_BEGIN_TOKEN = "//";
74
75
76
77
78 private int status = GET_REVISION;
79
80
81
82
83 private ChangeSet currentChange;
84
85
86
87
88 private String currentFile;
89
90
91
92
93
94 private String repoPath;
95
96 private Date startDate;
97
98 private Date endDate;
99
100 private String userDatePattern;
101
102
103
104
105 private static final Pattern PATTERN = Pattern.compile( "^\\.\\.\\. #(\\d+) " +
106 "change (\\d+) .* " +
107 "on (.*) " +
108 "by (.*)@" );
109
110 public PerforceChangeLogConsumer( String path, Date startDate, Date endDate, String userDatePattern,
111 ScmLogger logger )
112 {
113 super( logger );
114
115 this.startDate = startDate;
116 this.endDate = endDate;
117 this.userDatePattern = userDatePattern;
118 this.repoPath = path;
119 }
120
121
122
123
124
125 public List<ChangeSet> getModifications() throws ScmException
126 {
127
128
129
130
131
132 Map<Date, ChangeSet> groupedEntries = new LinkedHashMap<Date, ChangeSet>();
133 for ( int i = 0; i < entries.size(); i++ )
134 {
135 ChangeSet cs = (ChangeSet) entries.get( i );
136 ChangeSet hit = (ChangeSet) groupedEntries.get( cs.getDate() );
137 if ( hit != null )
138 {
139 if ( cs.getFiles().size() != 1 )
140 {
141 throw new ScmException( "Merge of entries failed. Bad entry size: " + cs.getFiles().size() );
142 }
143 hit.addFile( (ChangeFile) cs.getFiles().get( 0 ) );
144 }
145 else
146 {
147 groupedEntries.put( cs.getDate(), cs );
148 }
149 }
150
151 List<ChangeSet> result = new ArrayList<ChangeSet>();
152 result.addAll( groupedEntries.values() );
153
154 return result;
155 }
156
157
158
159
160
161
162 public void consumeLine( String line )
163 {
164 switch ( status )
165 {
166 case GET_REVISION:
167 processGetRevision( line );
168 break;
169 case GET_COMMENT_BEGIN:
170 status = GET_COMMENT;
171 break;
172 case GET_COMMENT:
173 processGetComment( line );
174 break;
175 default:
176 throw new IllegalStateException( "Unknown state: " + status );
177 }
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192 private void addEntry( ChangeSet entry, ChangeFile file )
193 {
194
195
196
197
198 if ( startDate != null && entry.getDate().before( startDate ) )
199 {
200 return;
201 }
202
203 if ( endDate != null && entry.getDate().after( endDate ) )
204 {
205 return;
206 }
207
208
209
210
211
212 entry.addFile( file );
213
214 entries.add( entry );
215 }
216
217
218
219
220
221
222
223 private void processGetRevision( String line )
224 {
225 if ( line.startsWith( FILE_BEGIN_TOKEN ) )
226 {
227 currentFile = line.substring( repoPath.length() + 1 );
228 return;
229 }
230
231 Matcher matcher = PATTERN.matcher( line );
232 if ( !matcher.find() )
233 {
234 return;
235 }
236
237 currentChange = new ChangeSet();
238 currentChange.setRevision( matcher.group( 1 ) );
239 currentChange.setDate( parseDate( matcher.group( 3 ), userDatePattern, PERFORCE_TIMESTAMP_PATTERN ) );
240 currentChange.setAuthor( matcher.group( 4 ) );
241
242 status = GET_COMMENT_BEGIN;
243 }
244
245
246
247
248
249
250
251 private void processGetComment( String line )
252 {
253 if ( line.equals( COMMENT_DELIMITER ) )
254 {
255 addEntry( currentChange, new ChangeFile( currentFile, currentChange.getRevision() ) );
256
257 status = GET_REVISION;
258 }
259 else
260 {
261 currentChange.setComment( currentChange.getComment() + line + "\n" );
262 }
263 }
264 }