001package org.apache.maven.scm.provider.starteam.command.checkin;
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
022import org.apache.maven.scm.ScmFile;
023import org.apache.maven.scm.ScmFileStatus;
024import org.apache.maven.scm.log.ScmLogger;
025import org.codehaus.plexus.util.cli.StreamConsumer;
026
027import java.io.File;
028import java.util.ArrayList;
029import java.util.List;
030
031/**
032 * @author <a href="mailto:dantran@gmail.com">Dan T. Tran</a>
033 * @author Olivier Lamy
034 *
035 */
036public class StarteamCheckInConsumer
037    implements StreamConsumer
038{
039    private String workingDirectory;
040
041    private ScmLogger logger;
042
043    private List<ScmFile> files = new ArrayList<ScmFile>();
044
045    /**
046     * the current directory entry being processed by the parser
047     */
048    private String currentDir = "";
049
050    /**
051     * Marks current directory data
052     */
053    private static final String DIR_MARKER = "(working dir: ";
054
055    /**
056     * Marks current file data
057     */
058    private static final String CHECKIN_MARKER = ": checked in";
059
060    /**
061     * Marks skipped file during update
062     */
063    private static final String SKIPPED_MARKER = ": skipped";
064
065    /**
066     * Marks current file data
067     */
068    private static final String LINKTO_MARKER = ": linked to";
069
070    public StarteamCheckInConsumer( ScmLogger logger, File basedir )
071    {
072        this.logger = logger;
073        this.workingDirectory = basedir.getPath().replace( '\\', '/' );
074    }
075
076    /** {@inheritDoc} */
077    public void consumeLine( String line )
078    {
079        if ( logger.isDebugEnabled() )
080        {
081            logger.debug( line );
082        }
083
084        int pos = 0;
085
086        if ( ( pos = line.indexOf( DIR_MARKER ) ) != -1 )
087        {
088            processDirectory( line, pos );
089        }
090        else if ( ( pos = line.indexOf( CHECKIN_MARKER ) ) != -1 )
091        {
092            processCheckedInFile( line, pos );
093        }
094        else if ( ( pos = line.indexOf( SKIPPED_MARKER ) ) != -1 )
095        {
096            processSkippedFile( line, pos );
097        }
098        else if ( ( pos = line.indexOf( LINKTO_MARKER ) ) != -1 )
099        {
100            //ignore
101        }
102        else
103        {
104            if ( logger.isWarnEnabled() )
105            {
106                logger.warn( "Unknown checkin ouput: " + line );
107            }
108        }
109
110    }
111
112    public List<ScmFile> getCheckedInFiles()
113    {
114        return files;
115    }
116
117    private void processDirectory( String line, int pos )
118    {
119        String dirPath = line.substring( pos + DIR_MARKER.length(), line.length() - 1 ).replace( '\\', '/' );
120
121        if ( !dirPath.startsWith( workingDirectory ) )
122        {
123            if ( logger.isInfoEnabled() )
124            {
125                logger.info( "Working directory: " + workingDirectory );
126                logger.info( "Checkin directory: " + dirPath );
127            }
128
129            throw new IllegalStateException( "Working and checkin directories are not on the same tree" );
130        }
131
132        this.currentDir = "." + dirPath.substring( workingDirectory.length() );
133    }
134
135    private void processCheckedInFile( String line, int pos )
136    {
137        String checkedInFilePath = this.currentDir + "/" + line.substring( 0, pos );
138
139        this.files.add( new ScmFile( checkedInFilePath, ScmFileStatus.CHECKED_OUT ) );
140
141        if ( logger.isInfoEnabled() )
142        {
143            logger.info( "Checked in: " + checkedInFilePath );
144        }
145    }
146
147    private void processSkippedFile( String line, int pos )
148    {
149        String skippedFilePath = this.currentDir + "/" + line.substring( 0, pos );
150
151        if ( logger.isInfoEnabled() )
152        {
153            logger.info( "Skipped: " + skippedFilePath );
154        }
155    }
156}