1 package org.apache.maven.scm.provider.clearcase.command.changelog;
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.ChangeFile;
23 import org.apache.maven.scm.ChangeSet;
24 import org.apache.maven.scm.log.ScmLogger;
25 import org.apache.maven.scm.util.AbstractConsumer;
26
27 import java.util.ArrayList;
28 import java.util.List;
29
30 /**
31 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
32 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
33 * @author Olivier Lamy
34 *
35 */
36 public class ClearCaseChangeLogConsumer
37 extends AbstractConsumer
38 {
39 /**
40 * Formatter used to parse Clearcase date/timestamp.
41 */
42 private static final String CLEARCASE_TIMESTAMP_PATTERN = "yyyyMMdd.HHmmss";
43
44 private static final String NAME_TAG = "NAME:";
45
46 private static final String USER_TAG = "USER:";
47
48 private static final String DATE_TAG = "DATE:";
49
50 private static final String COMMENT_TAG = "COMM:";
51
52 private static final String REVISION_TAG = "REVI:";
53
54 private List<ChangeSet> entries = new ArrayList<ChangeSet>();
55
56 // state machine constants for reading clearcase lshistory command output
57
58 /**
59 * expecting file information
60 */
61 private static final int GET_FILE = 1;
62
63 /**
64 * expecting date
65 */
66 private static final int GET_DATE = 2;
67
68 /**
69 * expecting comments
70 */
71 private static final int GET_COMMENT = 3;
72
73 /**
74 * expecting revision
75 */
76 private static final int GET_REVISION = 4;
77
78 /**
79 * current status of the parser
80 */
81 private int status = GET_FILE;
82
83 /**
84 * the current log entry being processed by the parser
85 */
86 private ChangeSet currentChange = null;
87
88 /**
89 * the current file being processed by the parser
90 */
91 private ChangeFile currentFile = null;
92
93 private String userDatePattern;
94
95 // ----------------------------------------------------------------------
96 //
97 // ----------------------------------------------------------------------
98
99 public ClearCaseChangeLogConsumer( ScmLogger logger, String userDatePattern )
100 {
101 super( logger );
102
103 this.userDatePattern = userDatePattern;
104 }
105
106 // ----------------------------------------------------------------------
107 //
108 // ----------------------------------------------------------------------
109
110 public List<ChangeSet> getModifications()
111 {
112 return entries;
113 }
114
115 // ----------------------------------------------------------------------
116 // StreamConsumer Implementation
117 // ----------------------------------------------------------------------
118
119 /** {@inheritDoc} */
120 public void consumeLine( String line )
121 {
122 switch ( getStatus() )
123 {
124 case GET_FILE:
125 processGetFile( line );
126 break;
127 case GET_DATE:
128 processGetDate( line );
129 break;
130 case GET_COMMENT:
131 processGetCommentAndUser( line );
132 break;
133 case GET_REVISION:
134 processGetRevision( line );
135 break;
136 default:
137 if ( getLogger().isWarnEnabled() )
138 {
139 getLogger().warn( "Unknown state: " + status );
140 }
141 }
142 }
143
144 // ----------------------------------------------------------------------
145 //
146 // ----------------------------------------------------------------------
147
148 /**
149 * Process the current input line in the Get File state.
150 *
151 * @param line a line of text from the clearcase log output
152 */
153 private void processGetFile( String line )
154 {
155 if ( line.startsWith( NAME_TAG ) )
156 {
157 setCurrentChange( new ChangeSet() );
158 setCurrentFile( new ChangeFile( line.substring( NAME_TAG.length(), line.length() ) ) );
159 setStatus( GET_DATE );
160 }
161 }
162
163 /**
164 * Process the current input line in the Get Date state.
165 *
166 * @param line a line of text from the clearcase log output
167 */
168 private void processGetDate( String line )
169 {
170 if ( line.startsWith( DATE_TAG ) )
171 {
172 getCurrentChange().setDate(
173 parseDate( line.substring( DATE_TAG.length() ), userDatePattern, CLEARCASE_TIMESTAMP_PATTERN ) );
174
175 setStatus( GET_COMMENT );
176 }
177 }
178
179 /**
180 * Process the current input line in the Get Comment state.
181 *
182 * @param line a line of text from the clearcase log output
183 */
184 private void processGetCommentAndUser( String line )
185 {
186 if ( line.startsWith( COMMENT_TAG ) )
187 {
188 String comm = line.substring( COMMENT_TAG.length() );
189
190 getCurrentChange().setComment( getCurrentChange().getComment() + comm + "\n" );
191 }
192 else if ( line.startsWith( USER_TAG ) )
193 {
194 getCurrentChange().setAuthor( line.substring( USER_TAG.length() ) );
195
196 // add entry, and set state to get file
197 getCurrentChange().addFile( getCurrentFile() );
198
199 entries.add( getCurrentChange() );
200
201 setStatus( GET_REVISION );
202 }
203 else
204 {
205 // keep gathering comments
206 getCurrentChange().setComment( getCurrentChange().getComment() + line + "\n" );
207 }
208 }
209
210 /**
211 * Process the current input line in the Get Revision.
212 *
213 * @param line a line of text from the clearcase log output
214 */
215 private void processGetRevision( String line )
216 {
217 if ( line.startsWith( REVISION_TAG ) )
218 {
219 getCurrentChange().setRevision( line.substring( REVISION_TAG.length() ) );
220
221 setStatus( GET_FILE );
222 }
223 }
224
225 /**
226 * Getter for property currentFile.
227 *
228 * @return Value of property currentFile.
229 */
230 private ChangeFile getCurrentFile()
231 {
232 return currentFile;
233 }
234
235 /**
236 * Setter for property currentFile.
237 *
238 * @param currentFile New value of property currentFile.
239 */
240 private void setCurrentFile( ChangeFile currentFile )
241 {
242 this.currentFile = currentFile;
243 }
244
245 /**
246 * Getter for property currentChange.
247 *
248 * @return Value of property currentChange.
249 */
250 private ChangeSet getCurrentChange()
251 {
252 return currentChange;
253 }
254
255 /**
256 * Setter for property currentLogEntry.
257 *
258 * @param currentChange New value of property currentLogEntry.
259 */
260 private void setCurrentChange( ChangeSet currentChange )
261 {
262 this.currentChange = currentChange;
263 }
264
265 /**
266 * Getter for property status.
267 *
268 * @return Value of property status.
269 */
270 private int getStatus()
271 {
272 return status;
273 }
274
275 /**
276 * Setter for property status.
277 *
278 * @param status New value of property status.
279 */
280 private void setStatus( int status )
281 {
282 this.status = status;
283 }
284 }