001    package org.apache.maven.scm.provider.vss.commands.status;
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 java.util.ArrayList;
023    import java.util.List;
024    
025    import org.apache.maven.scm.ScmFile;
026    import org.apache.maven.scm.ScmFileSet;
027    import org.apache.maven.scm.ScmFileStatus;
028    import org.apache.maven.scm.log.ScmLogger;
029    import org.apache.maven.scm.provider.vss.repository.VssScmProviderRepository;
030    import org.apache.maven.scm.util.AbstractConsumer;
031    import org.codehaus.plexus.util.cli.StreamConsumer;
032    
033    /**
034     * @author <a href="mailto:triek@thrx.de">Thorsten Riek</a>
035     * @version $Id: VssStatusConsumer.java 1056991 2011-01-09 18:09:10Z olamy $
036     */
037    public class VssStatusConsumer
038        extends AbstractConsumer
039        implements StreamConsumer
040    {
041    
042        /**
043         * expecting file information
044         */
045        private static final int DIFF_UNKNOWN = 0;
046    
047        /**
048         * expecting files to checkin
049         */
050        private static final int DIFF_LOCAL_FILES_NOT_IN_PROJECT = 1;
051    
052        /**
053         * expecting commit
054         */
055        private static final int DIFF_VSS_FILES_DIFFERENT_FROM_LOCAL_FILES = 2;
056    
057        /**
058         * expecting update / checkout
059         */
060        private static final int DIFF_VSS_FILES_NOT_IN_CURRENT_FOLDER = 3;
061    
062        /**
063         * expecting setting akt remote folder
064         */
065        private static final int DIFF_START_DIFFING_REMOTE = 4;
066    
067        /**
068         * expecting setting akt local folder
069         */
070        private static final int DIFF_START_DIFFING_LOCAL = 5;
071    
072        /**
073         * Marks Diffing remote project folder
074         */
075        private static final String START_DIFFING_REMOTE = "Diffing:";
076    
077        /**
078         * Marks Diffing local project folder
079         */
080        private static final String START_DIFFING_LOCAL = "Against:";
081    
082        /**
083         * Marks Local files not in the current project
084         */
085        private static final String LOCAL_FILES_NOT_IN_PROJECT = "Local files not in the current project:";
086    
087        /**
088         * Marks SourceSafe files different from local files
089         */
090        private static final String VSS_FILES_DIFFERENT_FROM_LOCAL_FILES = "SourceSafe files different from local files:";
091    
092        /**
093         * Marks SourceSafe files not in the current folder
094         */
095        private static final String VSS_FILES_NOT_IN_CURRENT_FOLDER = "SourceSafe files not in the current folder:";
096    
097        private String remoteProjectFolder = "";
098    
099        private String localFolder = "";
100    
101        private int lastState = 0;
102    
103        private List<ScmFile> updatedFiles = new ArrayList<ScmFile>();
104    
105        @SuppressWarnings( "unused" )
106        private VssScmProviderRepository repo;
107    
108        @SuppressWarnings( "unused" )
109        private ScmFileSet fileSet;
110    
111        public VssStatusConsumer( VssScmProviderRepository repo, ScmLogger logger, ScmFileSet fileSet )
112        {
113            super( logger );
114            this.repo = repo;
115            this.fileSet = fileSet;
116        }
117    
118        /** {@inheritDoc} */
119        public void consumeLine( String line )
120        {
121            if ( getLogger().isDebugEnabled() )
122            {
123                getLogger().debug( line );
124            }
125    
126            switch ( getLineStatus( line ) )
127            {
128                case DIFF_LOCAL_FILES_NOT_IN_PROJECT:
129                    lastState = DIFF_LOCAL_FILES_NOT_IN_PROJECT;
130                    break;
131                case DIFF_VSS_FILES_DIFFERENT_FROM_LOCAL_FILES:
132                    lastState = DIFF_VSS_FILES_DIFFERENT_FROM_LOCAL_FILES;
133                    break;
134                case DIFF_VSS_FILES_NOT_IN_CURRENT_FOLDER:
135                    lastState = DIFF_VSS_FILES_NOT_IN_CURRENT_FOLDER;
136                    break;
137                case DIFF_START_DIFFING_LOCAL:
138                    lastState = DIFF_START_DIFFING_LOCAL;
139                    processLocalFolder( line );
140                    break;
141                case DIFF_START_DIFFING_REMOTE:
142                    lastState = DIFF_START_DIFFING_REMOTE;
143                    processRemoteProjectFolder( line );
144                    break;
145                default:
146                    processLastStateFiles( line );
147                    break;
148            }
149        }
150    
151        /**
152         * Process the current input line in the Get File state.
153         * 
154         * @param line a line of text from the VSS log output
155         */
156        private void processLastStateFiles( String line )
157        {
158    
159            if ( line != null && line.trim().length() > 0 )
160            {
161                if ( lastState == DIFF_START_DIFFING_LOCAL )
162                {
163                    setLocalFolder( localFolder + line );
164                    getLogger().debug( "Local folder: " + localFolder );
165                }
166                else if ( lastState == DIFF_START_DIFFING_REMOTE )
167                {
168                    setRemoteProjectFolder( remoteProjectFolder + line );
169                    getLogger().debug( "Remote folder: " + localFolder );
170                }
171    
172                String[] fileLine = line.split( " " );
173                for ( int i = 0; i < fileLine.length; i++ )
174                {
175                    if ( fileLine[i].trim().length() > 0 )
176                    {
177                        if ( lastState == DIFF_LOCAL_FILES_NOT_IN_PROJECT )
178                        {
179                            updatedFiles.add( new ScmFile( localFolder + fileLine[i], ScmFileStatus.ADDED ) );
180                        }
181                        else if ( lastState == DIFF_VSS_FILES_NOT_IN_CURRENT_FOLDER )
182                        {
183                            updatedFiles.add( new ScmFile( localFolder + fileLine[i], ScmFileStatus.UPDATED ) );
184                        }
185                        else if ( lastState == DIFF_VSS_FILES_DIFFERENT_FROM_LOCAL_FILES )
186                        {
187                            updatedFiles.add( new ScmFile( localFolder + fileLine[i], ScmFileStatus.MODIFIED ) );
188                        }
189    
190                        if ( getLogger().isDebugEnabled() )
191                        {
192                            getLogger().debug( localFolder + fileLine[i] );
193                        }
194                    }
195                }
196            }
197            else
198            {
199                if ( getLogger().isDebugEnabled() )
200                {
201                    getLogger().debug( "processLastStateFiles:  empty line" );
202                }
203            }
204    
205        }
206    
207        /**
208         * Process the current input line in the Get File Path state.
209         * 
210         * @param line a line of text from the VSS log output
211         */
212        private void processLocalFolder( String line )
213        {
214    
215            setLocalFolder( line.substring( START_DIFFING_LOCAL.length() ).trim() );
216    
217        }
218    
219        /**
220         * Process the current input line in the Get File Path state.
221         * 
222         * @param line a line of text from the VSS log output
223         */
224        private void processRemoteProjectFolder( String line )
225        {
226    
227            setRemoteProjectFolder( line.substring( START_DIFFING_REMOTE.length() ).trim() );
228    
229        }
230    
231        /**
232         * Identify the status of a vss get line
233         * 
234         * @param line The line to process
235         * @return status
236         */
237        private int getLineStatus( String line )
238        {
239            int argument = DIFF_UNKNOWN;
240            if ( line.startsWith( LOCAL_FILES_NOT_IN_PROJECT ) )
241            {
242                argument = DIFF_LOCAL_FILES_NOT_IN_PROJECT;
243            }
244            else if ( line.startsWith( VSS_FILES_DIFFERENT_FROM_LOCAL_FILES ) )
245            {
246                argument = DIFF_VSS_FILES_DIFFERENT_FROM_LOCAL_FILES;
247            }
248            else if ( line.startsWith( VSS_FILES_NOT_IN_CURRENT_FOLDER ) )
249            {
250                argument = DIFF_VSS_FILES_NOT_IN_CURRENT_FOLDER;
251            }
252            //        else if ( line.startsWith( VSS_FILES_NOT_IN_CURRENT_FOLDER ) )
253            //        {
254            //            Project $/com.fum/fum-utilities/src/main/java/com/fum/utilities/protocol has no
255            //            corresponding folder
256            //            argument = DIFF_VSS_FILES_NOT_IN_CURRENT_FOLDER;
257            //        }
258            else if ( line.startsWith( START_DIFFING_LOCAL ) )
259            {
260                argument = DIFF_START_DIFFING_LOCAL;
261            }
262            else if ( line.startsWith( START_DIFFING_REMOTE ) )
263            {
264                argument = DIFF_START_DIFFING_REMOTE;
265            }
266    
267            return argument;
268        }
269    
270        public List<ScmFile> getUpdatedFiles()
271        {
272            return updatedFiles;
273        }
274    
275        private void setLocalFolder( String localFolder )
276        {
277            if ( localFolder != null && localFolder.trim().length() > 0 )
278            {
279                this.localFolder = localFolder.replace( java.io.File.separatorChar, '/' ) + "/";
280            }
281            else
282            {
283                this.localFolder = "";
284            }
285        }
286    
287        private void setRemoteProjectFolder( String remoteProjectFolder )
288        {
289            this.remoteProjectFolder = remoteProjectFolder;
290        }
291    
292    }