001    package org.apache.maven.scm.provider.perforce.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    
022    import org.apache.regexp.RE;
023    import org.apache.regexp.RESyntaxException;
024    import org.codehaus.plexus.util.cli.StreamConsumer;
025    
026    import java.io.PrintWriter;
027    import java.io.StringWriter;
028    
029    /**
030     * @author Mike Perham
031     * @version $Id: PerforceChangeLogConsumer.java 331276 2005-11-07 15:04:54Z
032     *          evenisse $
033     */
034    public class PerforceCheckInConsumer
035        implements StreamConsumer
036    {
037        private static final String CREATED_PATTERN = "^Change \\d+ created .+$";
038    
039        private static final String SUBMITTING_PATTERN = "^Submitting change \\d+\\.$";
040    
041        private static final String LOCKING_PATTERN = "^Locking \\d+ files \\.\\.\\.$";
042    
043        private static final String OP_PATTERN = "^[a-z]+ //[^#]+#\\d+$";
044    
045        // SCM-181 Two possible messages:
046        // "Change 94821 renamed change 94823 and submitted."
047        // "Change 94821 submitted."
048        private static final String COMPLETE_PATTERN = "^Change \\d+ .*submitted.$";
049    
050        public static final int STATE_CREATED = 1;
051    
052        public static final int STATE_SUBMITTING = 2;
053    
054        public static final int STATE_LOCKING = 3;
055    
056        public static final int STATE_OP = 4;
057    
058        public static final int STATE_COMPLETE = 5;
059    
060        public static final int STATE_ERROR = 6;
061    
062        private StringWriter errors = new StringWriter();
063    
064        private PrintWriter errorOutput = new PrintWriter( errors );
065    
066        private int currentState = STATE_CREATED;
067    
068        private RE opRegexp;
069    
070        public PerforceCheckInConsumer()
071        {
072            try
073            {
074                opRegexp = new RE( OP_PATTERN );
075            }
076            catch ( RESyntaxException ignored )
077            {
078                ignored.printStackTrace();
079            }
080        }
081    
082        /*
083         * Change 80835 created with 1 open file(s). Submitting change 80835.
084         * Locking 1 files ... add //depot/modules/cordoba/runtime-ear/foo.xml#1
085         * Change 80835 submitted.
086         */
087        /*
088         * Submitting change 80837. Locking 1 files ... edit
089         * //depot/modules/cordoba/runtime-ear/Foo.java#2 Submit validation failed --
090         * fix problems then use 'p4 submit -c 80837'. 'checkstyle' validation
091         * failed:
092         *
093         * depot/modules/cordoba/runtime-ear/Foo.java:3:1: Got an exception -
094         * expecting EOF, found '}'
095         */
096        /** {@inheritDoc} */
097        public void consumeLine( String line )
098        {
099            if ( line.startsWith( "... " ) )
100            {
101                //TODO log this somehow?
102                //System.out.println("Perforce: " + line);
103                return;
104            }
105    
106            switch ( currentState )
107            {
108                case STATE_CREATED:
109                    boolean created = new RE( CREATED_PATTERN ).match( line );
110                    if ( created )
111                    {
112                        currentState++;
113                        break;
114                    }
115                    error( line );
116                    break;
117                case STATE_SUBMITTING:
118                    boolean submitting = new RE( SUBMITTING_PATTERN ).match( line );
119                    if ( submitting )
120                    {
121                        currentState++;
122                        break;
123                    }
124                    error( line );
125                    break;
126                case STATE_LOCKING:
127                    boolean locked = new RE( LOCKING_PATTERN ).match( line );
128                    if ( locked )
129                    {
130                        currentState++;
131                        break;
132                    }
133                    error( line );
134                    break;
135                case STATE_OP:
136                    boolean operation = opRegexp.match( line );
137                    if ( operation )
138                    {
139                        break;
140                    }
141                    else if ( new RE( COMPLETE_PATTERN ).match( line ) )
142                    {
143                        currentState++;
144                        break;
145                    }
146                    error( line );
147                    break;
148                case STATE_ERROR:
149                    error( line );
150                    break;
151                default:
152            }
153        }
154    
155        private void error( String line )
156        {
157            //        if (currentState != STATE_ERROR) {
158            //            System.out.println("Unable to match: " + line + " State: " +
159            // currentState);
160            //            new Exception().printStackTrace();
161            //        }
162            currentState = STATE_ERROR;
163            errorOutput.println( line );
164        }
165    
166        public boolean isSuccess()
167        {
168            return currentState == STATE_COMPLETE;
169        }
170    
171        public String getOutput()
172        {
173            errorOutput.flush();
174            errors.flush();
175            return errors.toString();
176        }
177    }