001 package org.apache.maven.scm.provider.bazaar.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
022 import org.apache.maven.scm.ChangeFile;
023 import org.apache.maven.scm.ChangeSet;
024 import org.apache.maven.scm.ScmFileStatus;
025 import org.apache.maven.scm.log.ScmLogger;
026 import org.apache.maven.scm.provider.bazaar.command.BazaarConsumer;
027
028 import java.util.ArrayList;
029 import java.util.Date;
030 import java.util.List;
031
032 /**
033 * @author <a href="mailto:torbjorn@smorgrav.org">Torbjorn Eikli Smorgrav</a>
034 * @author Olivier Lamy
035 *
036 */
037 public class BazaarChangeLogConsumer
038 extends BazaarConsumer
039 {
040
041 private static final String BAZAAR_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss Z";
042
043 private static final String START_LOG_TAG = "-----";
044
045 private static final String REVNO_TAG = "revno: ";
046
047 private static final String AUTHOR_TAG = "committer: ";
048
049 private static final String TIME_STAMP_TOKEN = "timestamp: ";
050
051 private static final String MESSAGE_TOKEN = "message:";
052
053 private static final String BRANCH_NICK_TOKEN = "branch nick: ";
054
055 private static final String MERGED_TOKEN = "merged: ";
056
057 private static final String RENAME_SEPARATOR = " => ";
058
059 private List<ChangeSet> logEntries = new ArrayList<ChangeSet>();
060
061 private ChangeSet currentChange;
062
063 private ChangeSet lastChange;
064
065 private boolean isMergeEntry;
066
067 private String currentRevision;
068
069 private StringBuilder currentComment;
070
071 private String userDatePattern;
072
073 /**
074 * Null means not parsing message nor files, UNKNOWN means parsing message
075 */
076 private ScmFileStatus currentStatus = null;
077
078 public BazaarChangeLogConsumer( ScmLogger logger, String userDatePattern )
079 {
080 super( logger );
081
082 this.userDatePattern = userDatePattern;
083 }
084
085 public List<ChangeSet> getModifications()
086 {
087 return logEntries;
088 }
089
090 /** {@inheritDoc} */
091 public void doConsume( ScmFileStatus status, String line )
092 {
093 String tmpLine = line;
094
095 // Parse line
096 if ( line.startsWith( START_LOG_TAG ) )
097 {
098 //If last entry was part a merged entry
099 if ( isMergeEntry && lastChange != null )
100 {
101 String comment = lastChange.getComment();
102 comment += "\n[MAVEN]: Merged from " + currentChange.getAuthor();
103 comment += "\n[MAVEN]: " + currentChange.getDateFormatted();
104 comment += "\n[MAVEN]: " + currentChange.getComment();
105 lastChange.setComment( comment );
106 }
107
108 //Init a new changeset
109 currentChange = new ChangeSet();
110 currentChange.setFiles( new ArrayList<ChangeFile>() );
111 logEntries.add( currentChange );
112
113 //Reset memeber vars
114 currentComment = new StringBuilder();
115 currentStatus = null;
116 currentRevision = "";
117 isMergeEntry = false;
118 }
119 else if ( line.startsWith( MERGED_TOKEN ) )
120 {
121 //This is part of lastChange and is not a separate log entry
122 isMergeEntry = true;
123 logEntries.remove( currentChange );
124 if ( logEntries.size() > 0 )
125 {
126 lastChange = (ChangeSet) logEntries.get( logEntries.size() - 1 );
127 }
128 else
129 {
130 if ( getLogger().isWarnEnabled() )
131 {
132 getLogger().warn( "First entry was unexpectedly a merged entry" );
133 }
134 lastChange = null;
135 }
136 }
137 else if ( line.startsWith( REVNO_TAG ) )
138 {
139 tmpLine = line.substring( REVNO_TAG.length() );
140 tmpLine = tmpLine.trim();
141 currentRevision = tmpLine;
142 }
143 else if ( line.startsWith( AUTHOR_TAG ) )
144 {
145 tmpLine = line.substring( AUTHOR_TAG.length() );
146 tmpLine = tmpLine.trim();
147 currentChange.setAuthor( tmpLine );
148 }
149 else if ( line.startsWith( TIME_STAMP_TOKEN ) )
150 {
151 tmpLine = line.substring( TIME_STAMP_TOKEN.length() + 3 );
152 tmpLine = tmpLine.trim();
153 Date date = parseDate( tmpLine, userDatePattern, BAZAAR_TIME_PATTERN );
154 currentChange.setDate( date );
155 }
156 else if ( line.startsWith( MESSAGE_TOKEN ) )
157 {
158 currentStatus = ScmFileStatus.UNKNOWN;
159 }
160 else if ( status != null )
161 {
162 currentStatus = status;
163 }
164 else if ( currentStatus == ScmFileStatus.UNKNOWN )
165 {
166 currentComment.append( line );
167 currentChange.setComment( currentComment.toString() );
168 currentComment.append( "\n" );
169 }
170 else if ( currentStatus != null )
171 {
172 tmpLine = tmpLine.trim();
173 final ChangeFile changeFile;
174 if ( currentStatus == ScmFileStatus.RENAMED )
175 {
176 final String[] parts = tmpLine.split( RENAME_SEPARATOR );
177 if ( parts.length != 2 )
178 {
179 changeFile = new ChangeFile( tmpLine, currentRevision );
180 }
181 else
182 {
183 changeFile = new ChangeFile( parts[1], currentRevision );
184 changeFile.setOriginalName( parts[0] );
185 }
186 }
187 else
188 {
189 changeFile = new ChangeFile( tmpLine, currentRevision );
190 }
191 changeFile.setAction( currentStatus );
192 currentChange.addFile( changeFile );
193 }
194 else if ( line.startsWith( BRANCH_NICK_TOKEN ) )
195 {
196 //ignore
197 }
198 else
199 {
200 if ( getLogger().isWarnEnabled() )
201 {
202 getLogger().warn( "Could not figure out of: " + line );
203 }
204 }
205 }
206 }