001package org.apache.maven.scm.provider.clearcase.command.changelog; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.maven.scm.ChangeFile; 023import org.apache.maven.scm.ChangeSet; 024import org.apache.maven.scm.log.ScmLogger; 025import org.apache.maven.scm.util.AbstractConsumer; 026 027import java.util.ArrayList; 028import java.util.List; 029 030/** 031 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a> 032 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a> 033 * @author Olivier Lamy 034 * 035 */ 036public class ClearCaseChangeLogConsumer 037 extends AbstractConsumer 038{ 039 /** 040 * Formatter used to parse Clearcase date/timestamp. 041 */ 042 private static final String CLEARCASE_TIMESTAMP_PATTERN = "yyyyMMdd.HHmmss"; 043 044 private static final String NAME_TAG = "NAME:"; 045 046 private static final String USER_TAG = "USER:"; 047 048 private static final String DATE_TAG = "DATE:"; 049 050 private static final String COMMENT_TAG = "COMM:"; 051 052 private static final String REVISION_TAG = "REVI:"; 053 054 private List<ChangeSet> entries = new ArrayList<ChangeSet>(); 055 056 // state machine constants for reading clearcase lshistory command output 057 058 /** 059 * expecting file information 060 */ 061 private static final int GET_FILE = 1; 062 063 /** 064 * expecting date 065 */ 066 private static final int GET_DATE = 2; 067 068 /** 069 * expecting comments 070 */ 071 private static final int GET_COMMENT = 3; 072 073 /** 074 * expecting revision 075 */ 076 private static final int GET_REVISION = 4; 077 078 /** 079 * current status of the parser 080 */ 081 private int status = GET_FILE; 082 083 /** 084 * the current log entry being processed by the parser 085 */ 086 private ChangeSet currentChange = null; 087 088 /** 089 * the current file being processed by the parser 090 */ 091 private ChangeFile currentFile = null; 092 093 private String userDatePattern; 094 095 // ---------------------------------------------------------------------- 096 // 097 // ---------------------------------------------------------------------- 098 099 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}