001    package org.apache.maven.scm.provider.hg;
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.command.add.AddScmResult;
030    import org.apache.maven.scm.command.blame.BlameScmResult;
031    import org.apache.maven.scm.command.branch.BranchScmResult;
032    import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
033    import org.apache.maven.scm.command.checkin.CheckInScmResult;
034    import org.apache.maven.scm.command.checkout.CheckOutScmResult;
035    import org.apache.maven.scm.command.diff.DiffScmResult;
036    import org.apache.maven.scm.command.info.InfoScmResult;
037    import org.apache.maven.scm.command.list.ListScmResult;
038    import org.apache.maven.scm.command.remove.RemoveScmResult;
039    import org.apache.maven.scm.command.status.StatusScmResult;
040    import org.apache.maven.scm.command.tag.TagScmResult;
041    import org.apache.maven.scm.command.update.UpdateScmResult;
042    import org.apache.maven.scm.provider.AbstractScmProvider;
043    import org.apache.maven.scm.provider.ScmProviderRepository;
044    import org.apache.maven.scm.provider.hg.command.add.HgAddCommand;
045    import org.apache.maven.scm.provider.hg.command.blame.HgBlameCommand;
046    import org.apache.maven.scm.provider.hg.command.branch.HgBranchCommand;
047    import org.apache.maven.scm.provider.hg.command.changelog.HgChangeLogCommand;
048    import org.apache.maven.scm.provider.hg.command.checkin.HgCheckInCommand;
049    import org.apache.maven.scm.provider.hg.command.checkout.HgCheckOutCommand;
050    import org.apache.maven.scm.provider.hg.command.diff.HgDiffCommand;
051    import org.apache.maven.scm.provider.hg.command.info.HgInfoCommand;
052    import org.apache.maven.scm.provider.hg.command.inventory.HgListCommand;
053    import org.apache.maven.scm.provider.hg.command.remove.HgRemoveCommand;
054    import org.apache.maven.scm.provider.hg.command.status.HgStatusCommand;
055    import org.apache.maven.scm.provider.hg.command.tag.HgTagCommand;
056    import org.apache.maven.scm.provider.hg.command.update.HgUpdateCommand;
057    import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository;
058    import org.apache.maven.scm.repository.ScmRepositoryException;
059    import org.apache.maven.scm.repository.UnknownRepositoryStructure;
060    
061    /**
062     * Mercurial (HG) is a decentralized revision control system.
063     * <a href="http://www.selenic.com/mercurial">http://www.selenic.com/mercurial</a>
064     *
065     * @author <a href="mailto:thurner.rupert@ymono.net">thurner rupert</a>
066     * @version $Id: HgScmProvider.java 1063887 2011-01-26 21:58:58Z olamy $
067     * @plexus.component role="org.apache.maven.scm.provider.ScmProvider"
068     * role-hint="hg"
069     */
070    public class HgScmProvider
071        extends AbstractScmProvider
072    {
073        /** {@inheritDoc} */
074        public String getScmSpecificFilename()
075        {
076            return ".hg";
077        }
078    
079        private static class HgUrlParserResult
080        {
081            private List<String> messages = new ArrayList<String>();
082    
083            private ScmProviderRepository repository;
084        }
085    
086        /** {@inheritDoc} */
087        public ScmProviderRepository makeProviderScmRepository( String scmSpecificUrl, char delimiter )
088            throws ScmRepositoryException
089        {
090            HgUrlParserResult result = parseScmUrl( scmSpecificUrl );
091    
092            if ( result.messages.size() > 0 )
093            {
094                throw new ScmRepositoryException( "The scm url is invalid.", result.messages );
095            }
096    
097            return result.repository;
098        }
099    
100        private HgUrlParserResult parseScmUrl( String scmSpecificUrl )
101        {
102            HgUrlParserResult result = new HgUrlParserResult();
103    
104            String url = scmSpecificUrl;
105    
106            // ----------------------------------------------------------------------
107            // Do some sanity checking of the SVN url
108            // ----------------------------------------------------------------------
109    
110            if ( url.startsWith( "file" ) )
111            {
112                if ( !url.startsWith( "file:///" ) && !url.startsWith( "file://localhost/" ) )
113                {
114                    result.messages.add( "An hg 'file' url must be on the form 'file:///' or 'file://localhost/'." );
115    
116                    return result;
117                }
118            }
119            else if ( url.startsWith( "https" ) )
120            {
121                if ( !url.startsWith( "https://" ) )
122                {
123                    result.messages.add( "An hg 'http' url must be on the form 'https://'." );
124    
125                    return result;
126                }
127            }
128            else if ( url.startsWith( "http" ) )
129            {
130                if ( !url.startsWith( "http://" ) )
131                {
132                    result.messages.add( "An hg 'http' url must be on the form 'http://'." );
133    
134                    return result;
135                }
136            }
137            else
138            {
139                try
140                {
141                    @SuppressWarnings( "unused" )
142                    File file = new File( url );
143                }
144                catch ( Throwable e )
145                {
146                    result.messages.add( "The filename provided is not valid" );
147    
148                    return result;
149                }
150    
151            }
152    
153            result.repository = new HgScmProviderRepository( url );
154    
155            return result;
156        }
157    
158        /** {@inheritDoc} */
159        public ScmProviderRepository makeProviderScmRepository( File path )
160            throws ScmRepositoryException, UnknownRepositoryStructure
161        {
162            if ( path == null || !path.isDirectory() )
163            {
164                throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a valid directory." );
165            }
166    
167            File hgDir = new File( path, ".hg" );
168    
169            if ( !hgDir.exists() )
170            {
171                throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a hg directory." );
172            }
173    
174            return makeProviderScmRepository( path.getAbsolutePath(), ':' );
175        }
176    
177        /** {@inheritDoc} */
178        public List<String> validateScmUrl( String scmSpecificUrl, char delimiter )
179        {
180            HgUrlParserResult result = parseScmUrl( scmSpecificUrl );
181    
182            return result.messages;
183        }
184    
185        /** {@inheritDoc} */
186        public String getScmType()
187        {
188            return "hg";
189        }
190    
191        /** {@inheritDoc} */
192        public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
193            throws ScmException
194        {
195            HgAddCommand command = new HgAddCommand();
196    
197            command.setLogger( getLogger() );
198    
199            return (AddScmResult) command.execute( repository, fileSet, parameters );
200        }
201    
202        /** {@inheritDoc} */
203        public ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
204                                             CommandParameters parameters )
205            throws ScmException
206        {
207            HgChangeLogCommand command = new HgChangeLogCommand();
208    
209            command.setLogger( getLogger() );
210    
211            return (ChangeLogScmResult) command.execute( repository, fileSet, parameters );
212        }
213    
214        /** {@inheritDoc} */
215        public CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
216                                         CommandParameters parameters )
217            throws ScmException
218        {
219            HgCheckInCommand command = new HgCheckInCommand();
220    
221            command.setLogger( getLogger() );
222    
223            return (CheckInScmResult) command.execute( repository, fileSet, parameters );
224        }
225    
226        /** {@inheritDoc} */
227        public CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
228                                           CommandParameters parameters )
229            throws ScmException
230        {
231            HgCheckOutCommand command = new HgCheckOutCommand();
232    
233            command.setLogger( getLogger() );
234    
235            return (CheckOutScmResult) command.execute( repository, fileSet, parameters );
236        }
237    
238        /** {@inheritDoc} */
239        public TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
240            throws ScmException
241        {
242            HgTagCommand command = new HgTagCommand();
243    
244            command.setLogger( getLogger() );
245    
246            return (TagScmResult) command.execute( repository, fileSet, parameters );
247        }
248    
249        /** {@inheritDoc} */
250        public DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
251            throws ScmException
252        {
253            HgDiffCommand command = new HgDiffCommand();
254    
255            command.setLogger( getLogger() );
256    
257            return (DiffScmResult) command.execute( repository, fileSet, parameters );
258        }
259    
260        /** {@inheritDoc} */
261        public RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet,
262                                       CommandParameters parameters )
263            throws ScmException
264        {
265            HgRemoveCommand command = new HgRemoveCommand();
266    
267            command.setLogger( getLogger() );
268    
269            return (RemoveScmResult) command.execute( repository, fileSet, parameters );
270        }
271    
272        /** {@inheritDoc} */
273        public StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet,
274                                       CommandParameters parameters )
275            throws ScmException
276        {
277            HgStatusCommand command = new HgStatusCommand();
278    
279            command.setLogger( getLogger() );
280    
281            return (StatusScmResult) command.execute( repository, fileSet, parameters );
282        }
283    
284        /** {@inheritDoc} */
285        public UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet,
286                                       CommandParameters parameters )
287            throws ScmException
288        {
289            HgUpdateCommand command = new HgUpdateCommand();
290    
291            command.setLogger( getLogger() );
292    
293            return (UpdateScmResult) command.execute( repository, fileSet, parameters );
294        }
295    
296        /** {@inheritDoc} */
297        protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet,
298                                        CommandParameters parameters )
299            throws ScmException
300        {
301            HgBlameCommand command = new HgBlameCommand();
302    
303            command.setLogger( getLogger() );
304    
305            return (BlameScmResult) command.execute( repository, fileSet, parameters );
306        }
307    
308        /** {@inheritDoc} */
309        public BranchScmResult branch( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
310            throws ScmException
311        {
312            HgBranchCommand command = new HgBranchCommand();
313    
314            command.setLogger( getLogger() );
315    
316            return (BranchScmResult) command.execute( repository, fileSet, parameters );
317        }
318    
319        /**
320         * @since 1.5
321         * {@inheritDoc}
322         */    
323        @Override
324        protected ListScmResult list( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
325            throws ScmException
326        {
327            HgListCommand hgListCommand = new HgListCommand();
328            hgListCommand.setLogger( getLogger() );
329            return (ListScmResult) hgListCommand.executeCommand( repository, fileSet, parameters );
330    
331        }
332    
333        /**
334         * returns result of hg id -i
335         * @since 1.5
336         * @see org.apache.maven.scm.provider.AbstractScmProvider#info(org.apache.maven.scm.provider.ScmProviderRepository, org.apache.maven.scm.ScmFileSet, org.apache.maven.scm.CommandParameters)
337         */
338        @Override
339        public InfoScmResult info( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
340            throws ScmException
341        {
342            HgInfoCommand infoCommand = new HgInfoCommand();
343            infoCommand.setLogger( getLogger() );
344            return (InfoScmResult) infoCommand.execute( repository, fileSet, parameters );
345        }
346    }