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
163 public void consumeLine( String line )
164 {
165 switch ( status )
166 {
167 case GET_REVISION:
168 processGetRevision( line );
169 break;
170 case GET_COMMENT_BEGIN:
171 status = GET_COMMENT;
172 break;
173 case GET_COMMENT:
174 processGetComment( line );
175 break;
176 default:
177 throw new IllegalStateException( "Unknown state: " + status );
178 }
179 }
180
181
182
183
184
185
186
187
188
189
190
191
192
193 private void addEntry( ChangeSet entry, ChangeFile file )
194 {
195
196
197
198
199 if ( startDate != null && entry.getDate().before( startDate ) )
200 {
201 return;
202 }
203
204 if ( endDate != null && entry.getDate().after( endDate ) )
205 {
206 return;
207 }
208
209
210
211
212
213 entry.addFile( file );
214
215 entries.add( entry );
216 }
217
218
219
220
221
222
223
224 private void processGetRevision( String line )
225 {
226 if ( line.startsWith( FILE_BEGIN_TOKEN ) )
227 {
228 currentFile = line.substring( repoPath.length() + 1 );
229 return;
230 }
231
232 Matcher matcher = PATTERN.matcher( line );
233 if ( !matcher.find() )
234 {
235 return;
236 }
237
238 currentChange = new ChangeSet();
239 currentChange.setRevision( matcher.group( 1 ));
240 currentChange.setDate( parseDate( matcher.group( 3 ), userDatePattern, PERFORCE_TIMESTAMP_PATTERN ) );
241 currentChange.setAuthor( matcher.group( 4 ) );
242
243 status = GET_COMMENT_BEGIN;
244 }
245
246
247
248
249
250
251
252 private void processGetComment( String line )
253 {
254 if ( line.equals( COMMENT_DELIMITER ) )
255 {
256 addEntry( currentChange, new ChangeFile( currentFile, currentChange.getRevision() ) );
257
258 status = GET_REVISION;
259 }
260 else
261 {
262 currentChange.setComment( currentChange.getComment() + line + "\n" );
263 }
264 }
265 }