001    package org.apache.maven.scm.provider.perforce.command;
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.maven.scm.log.ScmLogger;
023    import org.apache.maven.scm.provider.perforce.PerforceScmProvider;
024    import org.apache.maven.scm.provider.perforce.repository.PerforceScmProviderRepository;
025    import org.codehaus.plexus.util.IOUtil;
026    import org.codehaus.plexus.util.cli.CommandLineException;
027    import org.codehaus.plexus.util.cli.Commandline;
028    
029    import java.io.BufferedReader;
030    import java.io.File;
031    import java.io.IOException;
032    import java.io.InputStreamReader;
033    
034    /**
035     * Encapsulates the 'p4 where' command which can be very useful in determining
036     * a file's location within the depot.  Use <code>getDepotLocation(String path)</code> to query
037     * the depot location for a particular file.  The data from p4 where looks like this:
038     * <p/>
039     * <pre>
040     * p4 where pom.xml
041     * //depot/modules/fabric/trunk/pom.xml //mikeperham-dt/depot/modules/fabric/trunk/pom.xml
042     * d:\perforce\depot\modules\fabric\trunk\pom.xml
043     * </pre>
044     *
045     * @author mperham
046     * @version $Id: $
047     */
048    public class PerforceWhereCommand
049    {
050        private ScmLogger logger = null;
051    
052        private PerforceScmProviderRepository repo = null;
053    
054        public PerforceWhereCommand( ScmLogger log, PerforceScmProviderRepository repos )
055        {
056            logger = log;
057            repo = repos;
058        }
059    
060        public String getDepotLocation( File file )
061        {
062            return getDepotLocation( file.getAbsolutePath() );
063        }
064    
065        /**
066         * @param filepath an absolute file path
067         * @return the absolute location of the given file within the Perforce repository or null if the file
068         *         does not exist in a mapping within the current clientspec.
069         */
070        public String getDepotLocation( String filepath )
071        {
072            if ( !PerforceScmProvider.isLive() )
073            {
074                return null;
075            }
076    
077            InputStreamReader isReader = null;
078            InputStreamReader isReaderErr = null;
079            try
080            {
081                Commandline command = PerforceScmProvider.createP4Command( repo, null );
082                command.createArg().setValue( "where" );
083                command.createArg().setValue( filepath );
084                if ( logger.isDebugEnabled() )
085                {
086                    logger.debug( PerforceScmProvider.clean( "Executing: " + command.toString() ) );
087                }
088                Process proc = command.execute();
089                isReader = new InputStreamReader( proc.getInputStream() );
090                isReaderErr = new InputStreamReader( proc.getErrorStream() );
091                BufferedReader br = new BufferedReader( isReader );
092                BufferedReader brErr = new BufferedReader( isReaderErr );
093                String line;
094                String path = null;
095                while ( ( line = br.readLine() ) != null )
096                {
097                    if ( line.indexOf( "not in client view" ) != -1 )
098                    {
099                        // uh oh, something bad is happening
100                        if ( logger.isErrorEnabled() )
101                        {
102                            logger.error( line );
103                        }
104                        return null;
105                    }
106                    if ( line.indexOf( "is not under" ) != -1 )
107                    {
108                        // uh oh, something bad is happening
109                        if ( logger.isErrorEnabled() )
110                        {
111                            logger.error( line );
112                        }
113                        return null;
114                    }
115    
116                    if ( logger.isDebugEnabled() )
117                    {
118                        logger.debug( line );
119                    }
120                    // verify that "//" appears twice in the line
121                    path = line.substring( 0, line.lastIndexOf( "//" ) - 1 );
122                }
123                // Check for errors
124                while ( ( line = brErr.readLine() ) != null )
125                {
126                    if ( line.indexOf( "not in client view" ) != -1 )
127                    {
128                        // uh oh, something bad is happening
129                        if ( logger.isErrorEnabled() )
130                        {
131                            logger.error( line );
132                        }
133                        return null;
134                    }
135                    if ( line.indexOf( "is not under" ) != -1 )
136                    {
137                        // uh oh, something bad is happening
138                        if ( logger.isErrorEnabled() )
139                        {
140                            logger.error( line );
141                        }
142                        return null;
143                    }
144    
145                    if ( logger.isDebugEnabled() )
146                    {
147                        logger.debug( line );
148                    }
149                }
150    
151                return path;
152            }
153            catch ( CommandLineException e )
154            {
155                if ( logger.isErrorEnabled() )
156                {
157                    logger.error( e );
158                }
159                throw new RuntimeException( e.getLocalizedMessage() );
160            }
161            catch ( IOException e )
162            {
163                if ( logger.isErrorEnabled() )
164                {
165                    logger.error( e );
166                }
167                throw new RuntimeException( e.getLocalizedMessage() );
168            }
169            finally
170            {
171                IOUtil.close( isReader );
172                IOUtil.close( isReaderErr );
173            }
174        }
175    }