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 * 035 */ 036public class SvnDiffConsumer extends AbstractConsumer { 037 // 038 // Index: plugin.jelly 039 // =================================================================== 040 // --- plugin.jelly (revision 124799) 041 // +++ plugin.jelly (working copy) 042 // 043 044 private static final String INDEX_TOKEN = "Index: "; 045 046 private static final String FILE_SEPARATOR_TOKEN = "==="; 047 048 private static final String START_REVISION_TOKEN = "---"; 049 050 private static final String END_REVISION_TOKEN = "+++"; 051 052 private static final String ADDED_LINE_TOKEN = "+"; 053 054 private static final String REMOVED_LINE_TOKEN = "-"; 055 056 private static final String UNCHANGED_LINE_TOKEN = " "; 057 058 private static final String CHANGE_SEPARATOR_TOKEN = "@@"; 059 060 private static final String NO_NEWLINE_TOKEN = "\\ No newline at end of file"; 061 062 private String currentFile; 063 064 private StringBuilder currentDifference; 065 066 private final List<ScmFile> changedFiles = new ArrayList<>(); 067 068 private final Map<String, CharSequence> differences = new HashMap<>(); 069 070 private final StringBuilder patch = new StringBuilder(); 071 072 // ---------------------------------------------------------------------- 073 // 074 // ---------------------------------------------------------------------- 075 076 public SvnDiffConsumer(File workingDirectory) { 077 // empty 078 } 079 080 // ---------------------------------------------------------------------- 081 // StreamConsumer Implementation 082 // ---------------------------------------------------------------------- 083 084 /** {@inheritDoc} */ 085 public void consumeLine(String line) { 086 if (line.startsWith(INDEX_TOKEN)) { 087 // start a new file 088 currentFile = line.substring(INDEX_TOKEN.length()); 089 090 changedFiles.add(new ScmFile(currentFile, ScmFileStatus.MODIFIED)); 091 092 currentDifference = new StringBuilder(); 093 094 differences.put(currentFile, currentDifference); 095 096 patch.append(line).append("\n"); 097 098 return; 099 } 100 101 if (currentFile == null) { 102 if (logger.isWarnEnabled()) { 103 logger.warn("Unparseable line: '" + line + "'"); 104 } 105 patch.append(line).append("\n"); 106 return; 107 } 108 109 if (line.startsWith(FILE_SEPARATOR_TOKEN)) { 110 // skip 111 patch.append(line).append("\n"); 112 } else if (line.startsWith(START_REVISION_TOKEN)) { 113 // skip, though could parse to verify filename, start revision 114 patch.append(line).append("\n"); 115 } else if (line.startsWith(END_REVISION_TOKEN)) { 116 // skip, though could parse to verify filename, end revision 117 patch.append(line).append("\n"); 118 } else if (line.startsWith(ADDED_LINE_TOKEN) 119 || line.startsWith(REMOVED_LINE_TOKEN) 120 || line.startsWith(UNCHANGED_LINE_TOKEN) 121 || line.startsWith(CHANGE_SEPARATOR_TOKEN) 122 || line.equals(NO_NEWLINE_TOKEN)) { 123 // add to buffer 124 currentDifference.append(line).append("\n"); 125 patch.append(line).append("\n"); 126 } else { 127 // TODO: handle property differences 128 129 if (logger.isWarnEnabled()) { 130 logger.warn("Unparseable line: '" + line + "'"); 131 } 132 patch.append(line).append("\n"); 133 // skip to next file 134 currentFile = null; 135 currentDifference = null; 136 } 137 } 138 139 public List<ScmFile> getChangedFiles() { 140 return changedFiles; 141 } 142 143 public Map<String, CharSequence> getDifferences() { 144 return differences; 145 } 146 147 public String getPatch() { 148 return patch.toString(); 149 } 150}