001 package org.apache.maven.scm.provider.hg.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 java.util.ArrayList;
023 import java.util.Date;
024 import java.util.List;
025 import java.util.Locale;
026
027 import org.apache.maven.scm.ChangeFile;
028 import org.apache.maven.scm.ChangeSet;
029 import org.apache.maven.scm.ScmFileStatus;
030 import org.apache.maven.scm.log.ScmLogger;
031 import org.apache.maven.scm.provider.hg.command.HgConsumer;
032
033 /**
034 * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
035 *
036 */
037 public class HgChangeLogConsumer
038 extends HgConsumer
039 {
040
041 private static final String TIME_PATTERN = "yyyy-MM-dd HH:mm:ss Z";
042
043 private static final String REVNO_TAG = "changeset: ";
044
045 private static final String TAG_TAG = "tag: ";
046
047 private static final String AUTHOR_TAG = "user: ";
048
049 private static final String TIME_STAMP_TOKEN = "date: ";
050
051 private static final String MESSAGE_TOKEN = "description:";
052
053 private static final String FILES_TOKEN = "files: ";
054
055 private String prevLine = "";
056
057 private String prevPrevLine = "";
058
059 private List<ChangeSet> logEntries = new ArrayList<ChangeSet>();
060
061 private ChangeSet currentChange;
062
063 private String currentRevision;
064
065 @SuppressWarnings( "unused" )
066 private String currentTag; // don't know what to do with this
067
068 private String userDatePattern;
069
070 private boolean spoolingComments;
071
072 private List<String> currentComment = null;
073
074 public HgChangeLogConsumer( ScmLogger logger, String userDatePattern )
075 {
076 super( logger );
077
078 this.userDatePattern = userDatePattern;
079 }
080
081 public List<ChangeSet> getModifications()
082 {
083 return logEntries;
084 }
085
086 /** {@inheritDoc} */
087 public void consumeLine( String line )
088 {
089
090 // override default behaviour which tries to pick through things for some standard messages. that
091 // does not apply here
092 doConsume( null, line );
093 }
094
095 /** {@inheritDoc} */
096 public void doConsume( ScmFileStatus status, String line )
097 {
098 String tmpLine = line;
099 // If current status == null then this is a new entry
100 // If the line == "" and previous line was "", then this is also a new entry
101 if ( ( line.equals( "" ) && ( prevLine.equals( "" ) && prevPrevLine.equals( "" ) ) ) || currentComment == null )
102 {
103 if ( currentComment != null )
104 {
105 StringBuilder comment = new StringBuilder();
106 for ( int i = 0; i < currentComment.size() - 1; i++ )
107 {
108 comment.append( currentComment.get( i ) );
109 if ( i + 1 < currentComment.size() - 1 )
110 {
111 comment.append( '\n' );
112 }
113 }
114 currentChange.setComment( comment.toString() );
115
116 }
117
118 spoolingComments = false;
119
120 //Init a new changeset
121 currentChange = new ChangeSet();
122 currentChange.setFiles( new ArrayList<ChangeFile>( 0 ) );
123 logEntries.add( currentChange );
124
125 //Reset memeber vars
126 currentComment = new ArrayList<String>();
127 currentRevision = "";
128 }
129
130 if ( spoolingComments )
131 {
132 currentComment.add( line );
133 }
134 else if ( line.startsWith( MESSAGE_TOKEN ) )
135 {
136 spoolingComments = true;
137 }
138 else if ( line.startsWith( REVNO_TAG ) )
139 {
140 tmpLine = line.substring( REVNO_TAG.length() );
141 tmpLine = tmpLine.trim();
142 currentRevision = tmpLine.substring( tmpLine.indexOf( ':' ) + 1 );
143 currentChange.setRevision( currentRevision );
144
145 }
146 else if ( line.startsWith( TAG_TAG ) )
147 {
148 tmpLine = line.substring( TAG_TAG.length() ).trim();
149 currentTag = tmpLine;
150 }
151 else if ( line.startsWith( AUTHOR_TAG ) )
152 {
153 tmpLine = line.substring( AUTHOR_TAG.length() );
154 tmpLine = tmpLine.trim();
155 currentChange.setAuthor( tmpLine );
156 }
157 else if ( line.startsWith( TIME_STAMP_TOKEN ) )
158 {
159 // TODO: FIX Date Parsing to match Mercurial or fix with template
160 tmpLine = line.substring( TIME_STAMP_TOKEN.length() ).trim();
161 Date date = parseDate( tmpLine, userDatePattern, TIME_PATTERN, Locale.ENGLISH );
162 currentChange.setDate( date );
163 }
164 else if ( line.startsWith( FILES_TOKEN ) )
165 {
166 tmpLine = line.substring( FILES_TOKEN.length() ).trim();
167 String[] files = tmpLine.split( " " );
168 for ( int i = 0; i < files.length; i++ )
169 {
170 String file = files[i];
171 ChangeFile changeFile = new ChangeFile( file, currentRevision );
172 currentChange.addFile( changeFile );
173 }
174 }
175 else if ( line.length() > 0 )
176 {
177 if ( getLogger().isWarnEnabled() )
178 {
179 getLogger().warn( "Could not figure out: " + line );
180 }
181 }
182
183 // record previous line
184 prevLine = line;
185 prevPrevLine = prevLine;
186 }
187 }