001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.svn.command.diff; 020 021import java.io.File; 022import java.util.ArrayList; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026 027import org.apache.maven.scm.ScmFile; 028import org.apache.maven.scm.ScmFileStatus; 029import org.apache.maven.scm.util.AbstractConsumer; 030 031/** 032 * @author <a href="mailto:brett@apache.org">Brett Porter</a> 033 * @author Olivier Lamy 034 */ 035public class SvnDiffConsumer extends AbstractConsumer { 036 // 037 // Index: plugin.jelly 038 // =================================================================== 039 // --- plugin.jelly (revision 124799) 040 // +++ plugin.jelly (working copy) 041 // 042 043 private static final String INDEX_TOKEN = "Index: "; 044 045 private static final String FILE_SEPARATOR_TOKEN = "==="; 046 047 private static final String START_REVISION_TOKEN = "---"; 048 049 private static final String END_REVISION_TOKEN = "+++"; 050 051 private static final String ADDED_LINE_TOKEN = "+"; 052 053 private static final String REMOVED_LINE_TOKEN = "-"; 054 055 private static final String UNCHANGED_LINE_TOKEN = " "; 056 057 private static final String CHANGE_SEPARATOR_TOKEN = "@@"; 058 059 private static final String NO_NEWLINE_TOKEN = "\\ No newline at end of file"; 060 061 private String currentFile; 062 063 private StringBuilder currentDifference; 064 065 private final List<ScmFile> changedFiles = new ArrayList<>(); 066 067 private final Map<String, CharSequence> differences = new HashMap<>(); 068 069 private final StringBuilder patch = new StringBuilder(); 070 071 // ---------------------------------------------------------------------- 072 // 073 // ---------------------------------------------------------------------- 074 075 public SvnDiffConsumer(File workingDirectory) { 076 // empty 077 } 078 079 // ---------------------------------------------------------------------- 080 // StreamConsumer Implementation 081 // ---------------------------------------------------------------------- 082 083 /** 084 * {@inheritDoc} 085 */ 086 public void consumeLine(String line) { 087 if (line.startsWith(INDEX_TOKEN)) { 088 // start a new file 089 currentFile = line.substring(INDEX_TOKEN.length()); 090 091 changedFiles.add(new ScmFile(currentFile, ScmFileStatus.MODIFIED)); 092 093 currentDifference = new StringBuilder(); 094 095 differences.put(currentFile, currentDifference); 096 097 patch.append(line).append("\n"); 098 099 return; 100 } 101 102 if (currentFile == null) { 103 if (logger.isWarnEnabled()) { 104 logger.warn("Unparseable line: '" + line + "'"); 105 } 106 patch.append(line).append("\n"); 107 return; 108 } 109 110 if (line.startsWith(FILE_SEPARATOR_TOKEN)) { 111 // skip 112 patch.append(line).append("\n"); 113 } else if (line.startsWith(START_REVISION_TOKEN)) { 114 // skip, though could parse to verify filename, start revision 115 patch.append(line).append("\n"); 116 } else if (line.startsWith(END_REVISION_TOKEN)) { 117 // skip, though could parse to verify filename, end revision 118 patch.append(line).append("\n"); 119 } else if (line.startsWith(ADDED_LINE_TOKEN) 120 || line.startsWith(REMOVED_LINE_TOKEN) 121 || line.startsWith(UNCHANGED_LINE_TOKEN) 122 || line.startsWith(CHANGE_SEPARATOR_TOKEN) 123 || line.equals(NO_NEWLINE_TOKEN)) { 124 // add to buffer 125 currentDifference.append(line).append("\n"); 126 patch.append(line).append("\n"); 127 } else { 128 // TODO: handle property differences 129 130 if (logger.isWarnEnabled()) { 131 logger.warn("Unparseable line: '" + line + "'"); 132 } 133 patch.append(line).append("\n"); 134 // skip to next file 135 currentFile = null; 136 currentDifference = null; 137 } 138 } 139 140 public List<ScmFile> getChangedFiles() { 141 return changedFiles; 142 } 143 144 public Map<String, CharSequence> getDifferences() { 145 return differences; 146 } 147 148 public String getPatch() { 149 return patch.toString(); 150 } 151}