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 }