001 package org.apache.maven.scm.provider.svn.svnexe.command.blame;
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.command.blame.BlameLine;
023 import org.apache.maven.scm.log.ScmLogger;
024 import org.apache.maven.scm.util.AbstractConsumer;
025 import org.apache.regexp.RE;
026 import org.apache.regexp.RESyntaxException;
027
028 import java.text.ParseException;
029 import java.text.SimpleDateFormat;
030 import java.util.ArrayList;
031 import java.util.Date;
032 import java.util.List;
033 import java.util.TimeZone;
034
035 /**
036 * @author Evgeny Mandrikov
037 * @author Olivier Lamy
038 * @since 1.4
039 */
040 public class SvnBlameConsumer
041 extends AbstractConsumer
042 {
043 private static final String SVN_TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss";
044
045 private static final String LINE_PATTERN = "line-number=\"(.*)\"";
046
047 private static final String REVISION_PATTERN = "revision=\"(.*)\"";
048
049 private static final String AUTHOR_PATTERN = "<author>(.*)</author>";
050
051 private static final String DATE_PATTERN = "<date>(.*)T(.*)\\.(.*)Z</date>";
052
053 /**
054 * @see #LINE_PATTERN
055 */
056 private RE lineRegexp;
057
058 /**
059 * @see #REVISION_PATTERN
060 */
061 private RE revisionRegexp;
062
063 /**
064 * @see #AUTHOR_PATTERN
065 */
066 private RE authorRegexp;
067
068 /**
069 * @see #DATE_PATTERN
070 */
071 private RE dateRegexp;
072
073 private SimpleDateFormat dateFormat;
074
075 private List<BlameLine> lines = new ArrayList<BlameLine>();
076
077 public SvnBlameConsumer( ScmLogger logger )
078 {
079 super( logger );
080
081 dateFormat = new SimpleDateFormat( SVN_TIMESTAMP_PATTERN );
082 dateFormat.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
083
084 try
085 {
086 lineRegexp = new RE( LINE_PATTERN );
087 revisionRegexp = new RE( REVISION_PATTERN );
088 authorRegexp = new RE( AUTHOR_PATTERN );
089 dateRegexp = new RE( DATE_PATTERN );
090 }
091 catch ( RESyntaxException ex )
092 {
093 throw new RuntimeException(
094 "INTERNAL ERROR: Could not create regexp to parse git log file. This shouldn't happen. Something is probably wrong with the oro installation.",
095 ex );
096 }
097 }
098
099 private int lineNumber;
100
101 private String revision;
102
103 private String author;
104
105 public void consumeLine( String line )
106 {
107 if ( lineRegexp.match( line ) )
108 {
109 String lineNumberStr = lineRegexp.getParen( 1 );
110 lineNumber = Integer.parseInt( lineNumberStr );
111 }
112 else if ( revisionRegexp.match( line ) )
113 {
114 revision = revisionRegexp.getParen( 1 );
115 }
116 else if ( authorRegexp.match( line ) )
117 {
118 author = authorRegexp.getParen( 1 );
119 }
120 else if ( dateRegexp.match( line ) )
121 {
122 String date = dateRegexp.getParen( 1 );
123 String time = dateRegexp.getParen( 2 );
124 Date dateTime = parseDateTime( date + " " + time );
125 lines.add( new BlameLine( dateTime, revision, author ) );
126 if ( getLogger().isDebugEnabled() )
127 {
128 getLogger().debug( "Author of line " + lineNumber + ": " + author + " (" + date + ")" );
129 }
130 }
131 }
132
133 protected Date parseDateTime( String dateTimeStr )
134 {
135 try
136 {
137 return dateFormat.parse( dateTimeStr );
138 }
139 catch ( ParseException e )
140 {
141 getLogger().error( "skip ParseException: " + e.getMessage() + " during parsing date " + dateTimeStr, e );
142 return null;
143 }
144 }
145
146 public List<BlameLine> getLines()
147 {
148 return lines;
149 }
150 }