001package org.apache.maven.scm.provider.perforce.command.checkout;
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.provider.perforce.command.AbstractPerforceConsumer;
025import org.apache.maven.scm.provider.perforce.command.PerforceVerbMapper;
026import org.codehaus.plexus.util.cli.StreamConsumer;
027
028import java.util.ArrayList;
029import java.util.List;
030import java.util.regex.Matcher;
031import java.util.regex.Pattern;
032
033/**
034 * @author Mike Perham
035 * @version $Id: PerforceChangeLogConsumer.java 331276 2005-11-07 15:04:54Z
036 *          evenisse $
037 */
038public class PerforceCheckOutConsumer
039    extends AbstractPerforceConsumer
040    implements StreamConsumer
041{
042    public static final int STATE_CLIENTSPEC = 0;
043
044    public static final int STATE_NORMAL = 1;
045
046    public static final int STATE_ERROR = 2;
047
048    private int currentState = STATE_CLIENTSPEC;
049
050    private Pattern fileRegexp = Pattern.compile( "([^#]+)#\\d+ - ([a-z]+)" );
051
052    private List<ScmFile> checkedout = new ArrayList<ScmFile>();
053
054    private String repo = null;
055
056    private String specname = null;
057
058    public PerforceCheckOutConsumer( String clientspec, String repoPath )
059    {
060        repo = repoPath;
061        specname = clientspec;
062    }
063
064    /*
065     * Client mperham-mikeperham-dt-maven saved.
066     */
067    /*
068     * //depot/modules/cordoba/runtime-ear/.j2ee#1 - deleted as
069     * d:\perforce\depot\modules\cordoba\runtime-ear\.j2ee
070     * //depot/modules/cordoba/runtime-ear/.project#1 - deleted as
071     * d:\perforce\depot\modules\cordoba\runtime-ear\.project
072     * //depot/modules/cordoba/runtime-ear/.runtime#1 - deleted as
073     * d:\perforce\depot\modules\cordoba\runtime-ear\.runtime
074     * //depot/modules/cordoba/runtime-ear/Foo.java#1 - deleted as
075     * d:\perforce\depot\modules\cordoba\runtime-ear\Foo.java
076     * //depot/modules/cordoba/runtime-ear/META-INF/.modulemaps#1 - deleted as
077     * d:\perforce\depot\modules\cordoba\runtime-ear\META-INF\.modulemaps
078     * //depot/modules/cordoba/runtime-ear/META-INF/application.xml#1 - deleted
079     * as d:\perforce\depot\modules\cordoba\runtime-ear\META-INF\application.xml
080     * //depot/modules/cordoba/runtime-ear/pom.xml#4 - deleted as
081     * d:\perforce\depot\modules\cordoba\runtime-ear\pom.xml
082     */
083    /*
084     * Invalid changelist/client/label/date '@somelabel'.
085     */
086    /** {@inheritDoc} */
087    public void consumeLine( String line )
088    {
089        if ( currentState == STATE_CLIENTSPEC
090            && ( line.startsWith( "Client " + specname + " saved." ) || line.startsWith( "Client " + specname
091                + " not changed." ) ) )
092        {
093            currentState = STATE_NORMAL;
094            return;
095        }
096
097        // Handle case where the clientspec is current
098        if ( currentState == STATE_NORMAL && line.indexOf( "ile(s) up-to-date" ) != -1 )
099        {
100            return;
101        }
102
103        Matcher matcher;
104        if ( currentState != STATE_ERROR && ( matcher = fileRegexp.matcher( line ) ).find() )
105        {
106            String location = matcher.group( 1 );
107            if ( location.startsWith( repo ) )
108            {
109                location = location.substring( repo.length() + 1 );
110            }
111            ScmFileStatus status = PerforceVerbMapper.toStatus( matcher.group( 2 ) );
112            if ( status != null )
113            {
114                // there are cases where Perforce prints out something but the file did not
115                // actually change (especially when force syncing).  Those files will have
116                // a null status.
117                checkedout.add( new ScmFile( location, status ) );
118            }
119            return;
120        }
121
122        error( line );
123    }
124
125    private void error( String line )
126    {
127        currentState = STATE_ERROR;
128        output.println( line );
129    }
130
131    public boolean isSuccess()
132    {
133        return currentState == STATE_NORMAL;
134    }
135
136    public List<ScmFile> getCheckedout()
137    {
138        return checkedout;
139    }
140}