001package 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 022import org.apache.maven.scm.ChangeFile; 023import org.apache.maven.scm.ChangeSet; 024import org.apache.maven.scm.ScmFileStatus; 025import org.apache.maven.scm.log.ScmLogger; 026import org.apache.maven.scm.provider.bazaar.command.BazaarConsumer; 027 028import java.util.ArrayList; 029import java.util.Date; 030import java.util.List; 031 032/** 033 * @author <a href="mailto:torbjorn@smorgrav.org">Torbjorn Eikli Smorgrav</a> 034 * @author Olivier Lamy 035 * 036 */ 037public 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}