View Javadoc
1   package org.apache.maven.scm.provider.svn.command.diff;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.scm.ScmFile;
23  import org.apache.maven.scm.ScmFileStatus;
24  import org.apache.maven.scm.util.AbstractConsumer;
25  
26  import java.io.File;
27  import java.util.ArrayList;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  /**
33   * @author <a href="mailto:brett@apache.org">Brett Porter</a>
34   * @author Olivier Lamy
35   *
36   */
37  public class SvnDiffConsumer
38          extends AbstractConsumer
39  {
40      //
41      // Index: plugin.jelly
42      // ===================================================================
43      // --- plugin.jelly        (revision 124799)
44      // +++ plugin.jelly        (working copy)
45      //
46  
47      private static final String INDEX_TOKEN = "Index: ";
48  
49      private static final String FILE_SEPARATOR_TOKEN = "===";
50  
51      private static final String START_REVISION_TOKEN = "---";
52  
53      private static final String END_REVISION_TOKEN = "+++";
54  
55      private static final String ADDED_LINE_TOKEN = "+";
56  
57      private static final String REMOVED_LINE_TOKEN = "-";
58  
59      private static final String UNCHANGED_LINE_TOKEN = " ";
60  
61      private static final String CHANGE_SEPARATOR_TOKEN = "@@";
62  
63      private static final String NO_NEWLINE_TOKEN = "\\ No newline at end of file";
64  
65      private String currentFile;
66  
67      private StringBuilder currentDifference;
68  
69      private final List<ScmFile> changedFiles = new ArrayList<>();
70  
71      private final Map<String, CharSequence> differences = new HashMap<>();
72  
73      private final StringBuilder patch = new StringBuilder();
74  
75      // ----------------------------------------------------------------------
76      //
77      // ----------------------------------------------------------------------
78  
79      public SvnDiffConsumer( File workingDirectory )
80      {
81          // empty
82      }
83  
84      // ----------------------------------------------------------------------
85      // StreamConsumer Implementation
86      // ----------------------------------------------------------------------
87  
88      /** {@inheritDoc} */
89      public void consumeLine( String line )
90      {
91          if ( line.startsWith( INDEX_TOKEN ) )
92          {
93              // start a new file
94              currentFile = line.substring( INDEX_TOKEN.length() );
95  
96              changedFiles.add( new ScmFile( currentFile, ScmFileStatus.MODIFIED ) );
97  
98              currentDifference = new StringBuilder();
99  
100             differences.put( currentFile, currentDifference );
101 
102             patch.append( line ).append( "\n" );
103 
104             return;
105         }
106 
107         if ( currentFile == null )
108         {
109             if ( logger.isWarnEnabled() )
110             {
111                 logger.warn( "Unparseable line: '" + line + "'" );
112             }
113             patch.append( line ).append( "\n" );
114             return;
115         }
116 
117         if ( line.startsWith( FILE_SEPARATOR_TOKEN ) )
118         {
119             // skip
120             patch.append( line ).append( "\n" );
121         }
122         else if ( line.startsWith( START_REVISION_TOKEN ) )
123         {
124             // skip, though could parse to verify filename, start revision
125             patch.append( line ).append( "\n" );
126         }
127         else if ( line.startsWith( END_REVISION_TOKEN ) )
128         {
129             // skip, though could parse to verify filename, end revision
130             patch.append( line ).append( "\n" );
131         }
132         else if ( line.startsWith( ADDED_LINE_TOKEN ) || line.startsWith( REMOVED_LINE_TOKEN )
133             || line.startsWith( UNCHANGED_LINE_TOKEN ) || line.startsWith( CHANGE_SEPARATOR_TOKEN )
134             || line.equals( NO_NEWLINE_TOKEN ) )
135         {
136             // add to buffer
137             currentDifference.append( line ).append( "\n" );
138             patch.append( line ).append( "\n" );
139         }
140         else
141         {
142             // TODO: handle property differences
143 
144             if ( logger.isWarnEnabled() )
145             {
146                 logger.warn( "Unparseable line: '" + line + "'" );
147             }
148             patch.append( line ).append( "\n" );
149             // skip to next file
150             currentFile = null;
151             currentDifference = null;
152         }
153     }
154 
155     public List<ScmFile> getChangedFiles()
156     {
157         return changedFiles;
158     }
159 
160     public Map<String, CharSequence> getDifferences()
161     {
162         return differences;
163     }
164 
165     public String getPatch()
166     {
167         return patch.toString();
168     }
169 
170 }