View Javadoc
1   package org.apache.maven.scm.provider.starteam.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 java.io.File;
23  import java.util.ArrayList;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.maven.scm.ScmFile;
29  import org.apache.maven.scm.ScmFileStatus;
30  import org.apache.maven.scm.log.ScmLogger;
31  import org.codehaus.plexus.util.cli.StreamConsumer;
32  
33  /**
34   * @author <a href="mailto:dantran@gmail.com">Dan T. Tran</a>
35   *
36   */
37  public class StarteamDiffConsumer
38      implements StreamConsumer
39  {
40      private static final String WORKING_DIR_TOKEN = "(working dir: ";
41  
42      private static final String PATCH_SEPARATOR_TOKEN = "--------------";
43  
44      private static final String REVISION_TOKEN = " Revision: ";
45  
46      private static final String ONDISK_TOKEN = " (on disk)";
47  
48      private static final String ADDED_LINE_TOKEN = "+";
49  
50      private static final String REMOVED_LINE_TOKEN = "-";
51  
52      private static final String UNCHANGED_LINE_TOKEN = " ";
53  
54      private ScmLogger logger;
55  
56      @SuppressWarnings( "unused" )
57      private String currentDir = "";
58  
59      private boolean diffBlockProcessingStarted = false;
60  
61      private boolean revisionBlockStarted = false;
62  
63      private String currentFile;
64  
65      private StringBuilder currentDifference;
66  
67      private List<ScmFile> changedFiles = new ArrayList<ScmFile>();
68  
69      private Map<String,CharSequence> differences = new HashMap<String,CharSequence>();
70  
71      private StringBuilder patch = new StringBuilder();
72  
73      // ----------------------------------------------------------------------
74      //
75      // ----------------------------------------------------------------------
76  
77      public StarteamDiffConsumer( ScmLogger logger, File workingDirectory )
78      {
79          this.logger = logger;
80      }
81  
82      // ----------------------------------------------------------------------
83      // StreamConsumer Implementation
84      // ----------------------------------------------------------------------
85  
86      /** {@inheritDoc} */
87      public void consumeLine( String line )
88      {
89          int pos = 0;
90  
91          if ( logger.isDebugEnabled() )
92          {
93              logger.debug( line );
94          }
95  
96          patch.append( line ).append( "\n" );
97  
98          if ( line.trim().length() == 0 )
99          {
100             return;
101         }
102 
103         if ( ( pos = line.indexOf( WORKING_DIR_TOKEN ) ) != -1 )
104         {
105             processGetDir( line, pos );
106 
107             return;
108         }
109 
110         if ( line.startsWith( PATCH_SEPARATOR_TOKEN ) )
111         {
112             diffBlockProcessingStarted = !diffBlockProcessingStarted;
113 
114             if ( diffBlockProcessingStarted )
115             {
116                 if ( revisionBlockStarted )
117                 {
118                     throw new IllegalStateException( "Missing second Revision line or local copy line " );
119                 }
120             }
121 
122             return;
123         }
124 
125         if ( ( pos = line.indexOf( REVISION_TOKEN ) ) != -1 )
126         {
127             if ( revisionBlockStarted )
128             {
129                 revisionBlockStarted = false;
130             }
131             else
132             {
133                 extractCurrentFile( line, pos );
134 
135                 revisionBlockStarted = true;
136             }
137 
138             return;
139         }
140 
141         if ( ( pos = line.indexOf( ONDISK_TOKEN ) ) != -1 )
142         {
143             if ( revisionBlockStarted )
144             {
145                 revisionBlockStarted = false;
146             }
147             else
148             {
149                 throw new IllegalStateException( "Working copy line found at the wrong state " );
150             }
151 
152             return;
153         }
154 
155         if ( !diffBlockProcessingStarted )
156         {
157             if ( logger.isWarnEnabled() )
158             {
159                 logger.warn( "Unparseable line: '" + line + "'" );
160             }
161 
162             return;
163         }
164 
165         if ( line.startsWith( ADDED_LINE_TOKEN ) || line.startsWith( REMOVED_LINE_TOKEN )
166             || line.startsWith( UNCHANGED_LINE_TOKEN ) )
167         {
168             // add to buffer
169             currentDifference.append( line ).append( "\n" );
170         }
171         else
172         {
173             if ( logger.isWarnEnabled() )
174             {
175                 logger.warn( "Unparseable line: '" + line + "'" );
176             }
177         }
178     }
179 
180     /**
181      * Process the current input line in the Get Directory
182      *
183      * @param line a line of text from the Starteam log output
184      */
185     private void processGetDir( String line, int pos )
186     {
187         String dirPath = line.substring( pos + WORKING_DIR_TOKEN.length(), line.length() - 1 ).replace( '\\', '/' );
188 
189         this.currentDir = dirPath;
190     }
191 
192     private void extractCurrentFile( String line, int pos )
193     {
194         currentFile = line.substring( 0, pos );
195 
196         changedFiles.add( new ScmFile( currentFile, ScmFileStatus.MODIFIED ) );
197 
198         currentDifference = new StringBuilder();
199 
200         differences.put( currentFile, currentDifference );
201     }
202 
203     public List<ScmFile> getChangedFiles()
204     {
205         return changedFiles;
206     }
207 
208     public Map<String,CharSequence> getDifferences()
209     {
210         return differences;
211     }
212 
213     public String getPatch()
214     {
215         return patch.toString();
216     }
217 
218 }