001    package org.apache.maven.scm.provider.git;
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.io.File;
023    import java.util.ArrayList;
024    import java.util.List;
025    
026    import org.apache.maven.scm.CommandParameters;
027    import org.apache.maven.scm.ScmException;
028    import org.apache.maven.scm.ScmFileSet;
029    import org.apache.maven.scm.ScmResult;
030    import org.apache.maven.scm.command.add.AddScmResult;
031    import org.apache.maven.scm.command.blame.BlameScmResult;
032    import org.apache.maven.scm.command.branch.BranchScmResult;
033    import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
034    import org.apache.maven.scm.command.checkin.CheckInScmResult;
035    import org.apache.maven.scm.command.checkout.CheckOutScmResult;
036    import org.apache.maven.scm.command.diff.DiffScmResult;
037    import org.apache.maven.scm.command.export.ExportScmResult;
038    import org.apache.maven.scm.command.info.InfoScmResult;
039    import org.apache.maven.scm.command.list.ListScmResult;
040    import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
041    import org.apache.maven.scm.command.remove.RemoveScmResult;
042    import org.apache.maven.scm.command.status.StatusScmResult;
043    import org.apache.maven.scm.command.tag.TagScmResult;
044    import org.apache.maven.scm.command.update.UpdateScmResult;
045    import org.apache.maven.scm.provider.AbstractScmProvider;
046    import org.apache.maven.scm.provider.ScmProviderRepository;
047    import org.apache.maven.scm.provider.git.command.GitCommand;
048    import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
049    import org.apache.maven.scm.repository.ScmRepositoryException;
050    import org.apache.maven.scm.repository.UnknownRepositoryStructure;
051    
052    /**
053     * SCM Provider for git
054     *
055     *
056     * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
057     * @version $Id: AbstractGitScmProvider.java 1204747 2011-11-21 23:16:01Z olamy $
058     */
059    public abstract class AbstractGitScmProvider
060        extends AbstractScmProvider
061    {
062    
063        // ----------------------------------------------------------------------
064        //
065        // ----------------------------------------------------------------------
066    
067        /**
068         * Internal class
069         */
070        private static class ScmUrlParserResult
071        {
072            private List<String> messages = new ArrayList<String>();
073    
074            private ScmProviderRepository repository;
075        }
076    
077        // ----------------------------------------------------------------------
078        // ScmProvider Implementation
079        // ----------------------------------------------------------------------
080    
081        /** {@inheritDoc} */
082        public String getScmSpecificFilename()
083        {
084            return ".git";
085        }
086    
087        /** {@inheritDoc} */
088        public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter )
089            throws ScmRepositoryException
090        {
091            try
092            {
093                ScmUrlParserResult result = parseScmUrl( scmSpecificUrl, delimiter );
094        
095                if ( result.messages.size() > 0 )
096                {
097                    throw new ScmRepositoryException( "The scm url is invalid.", result.messages );
098                }
099        
100                return result.repository;
101            }
102            catch ( ScmException e )
103            {
104                // XXX We should allow throwing of SCMException.
105                throw new ScmRepositoryException( "Error creating the scm repository", e );
106            }
107        }
108    
109        /** {@inheritDoc} */
110        public ScmProviderRepository makeProviderScmRepository( File path )
111            throws ScmRepositoryException, UnknownRepositoryStructure
112        {
113            if ( path == null )
114            {
115                throw new NullPointerException( "Path argument is null" );
116            }
117    
118            if ( !path.isDirectory() )
119            {
120                throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a valid directory." );
121            }
122    
123            if ( !new File( path, ".git" ).exists() )
124            {
125                throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a git checkout directory." );
126            }
127    
128            try
129            {
130                return makeProviderScmRepository( getRepositoryURL( path ), ':' );
131            }
132            catch ( ScmException e )
133            {
134                // XXX We should allow throwing of SCMException.
135                throw new ScmRepositoryException( "Error creating the scm repository", e );
136            }
137        }
138    
139        protected abstract String getRepositoryURL( File path )
140            throws ScmException;
141    
142        /** {@inheritDoc} */
143        public List<String> validateScmUrl( String scmSpecificUrl, char delimiter )
144        {
145            List<String> messages = new ArrayList<String>();
146            try
147            {
148                makeProviderScmRepository( scmSpecificUrl, delimiter );
149            }
150            catch ( ScmRepositoryException e )
151            {
152                messages = e.getValidationMessages();
153            }
154            return messages;
155        }
156    
157        /** {@inheritDoc} */
158        public String getScmType()
159        {
160            return "git";
161        }
162    
163        // ----------------------------------------------------------------------
164        //
165        // ----------------------------------------------------------------------
166    
167        /**
168         * The git-submodule(1) command is available since Git 1.5.3, so modules will
169         * be activated in a later stage
170         */
171        private ScmUrlParserResult parseScmUrl( String scmSpecificUrl, char delimiter )
172            throws ScmException
173        {
174            ScmUrlParserResult result = new ScmUrlParserResult();
175    
176            result.repository = new GitScmProviderRepository( scmSpecificUrl );
177    
178            return result;
179        }
180    
181        protected abstract GitCommand getAddCommand();
182    
183        /** {@inheritDoc} */
184        public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
185            throws ScmException
186        {
187            return (AddScmResult) executeCommand( getAddCommand(), repository, fileSet, parameters );
188        }
189    
190        protected abstract GitCommand getBranchCommand();
191    
192        /** {@inheritDoc} */
193        protected BranchScmResult branch( ScmProviderRepository repository, ScmFileSet fileSet,
194                                          CommandParameters parameters )
195            throws ScmException
196        {
197            return (BranchScmResult) executeCommand( getBranchCommand(), repository, fileSet, parameters );
198        }
199    
200        protected abstract GitCommand getChangeLogCommand();
201    
202        /** {@inheritDoc} */
203        public ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
204                                             CommandParameters parameters )
205            throws ScmException
206        {
207            return (ChangeLogScmResult) executeCommand( getChangeLogCommand(), repository, fileSet, parameters );
208        }
209    
210        protected abstract GitCommand getCheckInCommand();
211    
212        /** {@inheritDoc} */
213        public CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
214                                         CommandParameters parameters )
215            throws ScmException
216        {
217            return (CheckInScmResult) executeCommand( getCheckInCommand(), repository, fileSet, parameters );
218        }
219    
220        protected abstract GitCommand getCheckOutCommand();
221    
222        /** {@inheritDoc} */
223        public CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
224                                           CommandParameters parameters )
225            throws ScmException
226        {
227            return (CheckOutScmResult) executeCommand( getCheckOutCommand(), repository, fileSet, parameters );
228        }
229    
230        protected abstract GitCommand getDiffCommand();
231    
232        /** {@inheritDoc} */
233        public DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
234            throws ScmException
235        {
236            return (DiffScmResult) executeCommand( getDiffCommand(), repository, fileSet, parameters );
237        }
238    
239        protected abstract GitCommand getExportCommand();
240    
241        /** {@inheritDoc} */
242        protected ExportScmResult export( ScmProviderRepository repository, ScmFileSet fileSet,
243                                          CommandParameters parameters )
244            throws ScmException
245        {
246            return (ExportScmResult) executeCommand( getExportCommand(), repository, fileSet, parameters );
247        }
248    
249        protected abstract GitCommand getRemoveCommand();
250    
251        /** {@inheritDoc} */
252        public RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
253            throws ScmException
254        {
255            return (RemoveScmResult) executeCommand( getRemoveCommand(), repository, fileSet, parameters );
256        }
257    
258        protected abstract GitCommand getStatusCommand();
259    
260        /** {@inheritDoc} */
261        public StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
262            throws ScmException
263        {
264            return (StatusScmResult) executeCommand( getStatusCommand(), repository, fileSet, parameters );
265        }
266    
267        protected abstract GitCommand getTagCommand();
268    
269        /** {@inheritDoc} */
270        public TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
271            throws ScmException
272        {
273            return (TagScmResult) executeCommand( getTagCommand(), repository, fileSet, parameters );
274        }
275    
276        protected abstract GitCommand getUpdateCommand();
277    
278        /** {@inheritDoc} */
279        public UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
280            throws ScmException
281        {
282            return (UpdateScmResult) executeCommand( getUpdateCommand(), repository, fileSet, parameters );
283        }
284    
285        protected ScmResult executeCommand( GitCommand command, ScmProviderRepository repository, ScmFileSet fileSet,
286                                            CommandParameters parameters )
287            throws ScmException
288        {
289            command.setLogger( getLogger() );
290    
291            return command.execute( repository, fileSet, parameters );
292        }
293    
294        protected abstract GitCommand getListCommand();
295    
296        /** {@inheritDoc} */
297        public ListScmResult list( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
298            throws ScmException
299        {
300            GitCommand cmd = getListCommand();
301    
302            return (ListScmResult) executeCommand( cmd, repository, fileSet, parameters );
303        }
304    
305        protected abstract GitCommand getInfoCommand();
306    
307        public InfoScmResult info( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
308            throws ScmException
309        {
310            GitCommand cmd = getInfoCommand();
311    
312            return (InfoScmResult) executeCommand( cmd, repository, fileSet, parameters );
313        }
314    
315        /** {@inheritDoc} */
316        protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
317            throws ScmException
318        {
319            GitCommand cmd = getBlameCommand();
320    
321            return (BlameScmResult) executeCommand( cmd, repository, fileSet, parameters );
322        }
323    
324        protected abstract GitCommand getBlameCommand();
325        
326        /** {@inheritDoc} */
327        public RemoteInfoScmResult remoteInfo( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
328            throws ScmException
329        {
330            GitCommand cmd = getRemoteInfoCommand();
331    
332            return (RemoteInfoScmResult) executeCommand( cmd, repository, fileSet, parameters );
333        }
334    
335        protected abstract GitCommand getRemoteInfoCommand();
336    
337    }