001package 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
022import java.io.File;
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.maven.scm.CommandParameters;
027import org.apache.maven.scm.ScmException;
028import org.apache.maven.scm.ScmFileSet;
029import org.apache.maven.scm.command.add.AddScmResult;
030import org.apache.maven.scm.command.blame.BlameScmResult;
031import org.apache.maven.scm.command.branch.BranchScmResult;
032import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
033import org.apache.maven.scm.command.checkin.CheckInScmResult;
034import org.apache.maven.scm.command.checkout.CheckOutScmResult;
035import org.apache.maven.scm.command.diff.DiffScmResult;
036import org.apache.maven.scm.command.info.InfoScmResult;
037import org.apache.maven.scm.command.list.ListScmResult;
038import org.apache.maven.scm.command.remove.RemoveScmResult;
039import org.apache.maven.scm.command.status.StatusScmResult;
040import org.apache.maven.scm.command.tag.TagScmResult;
041import org.apache.maven.scm.command.update.UpdateScmResult;
042import org.apache.maven.scm.provider.AbstractScmProvider;
043import org.apache.maven.scm.provider.ScmProviderRepository;
044import org.apache.maven.scm.provider.hg.command.add.HgAddCommand;
045import org.apache.maven.scm.provider.hg.command.blame.HgBlameCommand;
046import org.apache.maven.scm.provider.hg.command.branch.HgBranchCommand;
047import org.apache.maven.scm.provider.hg.command.changelog.HgChangeLogCommand;
048import org.apache.maven.scm.provider.hg.command.checkin.HgCheckInCommand;
049import org.apache.maven.scm.provider.hg.command.checkout.HgCheckOutCommand;
050import org.apache.maven.scm.provider.hg.command.diff.HgDiffCommand;
051import org.apache.maven.scm.provider.hg.command.info.HgInfoCommand;
052import org.apache.maven.scm.provider.hg.command.inventory.HgListCommand;
053import org.apache.maven.scm.provider.hg.command.remove.HgRemoveCommand;
054import org.apache.maven.scm.provider.hg.command.status.HgStatusCommand;
055import org.apache.maven.scm.provider.hg.command.tag.HgTagCommand;
056import org.apache.maven.scm.provider.hg.command.update.HgUpdateCommand;
057import org.apache.maven.scm.provider.hg.repository.HgScmProviderRepository;
058import org.apache.maven.scm.repository.ScmRepositoryException;
059import 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 *
067 * @plexus.component role="org.apache.maven.scm.provider.ScmProvider"
068 * role-hint="hg"
069 */
070public 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 )
163        {
164            throw new NullPointerException( "Path argument is null" );
165        }
166
167        if ( !path.isDirectory() )
168        {
169            throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a valid directory." );
170        }
171
172        File hgDir = new File( path, ".hg" );
173
174        if ( !hgDir.exists() )
175        {
176            throw new ScmRepositoryException( path.getAbsolutePath() + " isn't a hg directory." );
177        }
178
179        return makeProviderScmRepository( path.getAbsolutePath(), ':' );
180    }
181
182    /** {@inheritDoc} */
183    public List<String> validateScmUrl( String scmSpecificUrl, char delimiter )
184    {
185        HgUrlParserResult result = parseScmUrl( scmSpecificUrl );
186
187        return result.messages;
188    }
189
190    /** {@inheritDoc} */
191    public String getScmType()
192    {
193        return "hg";
194    }
195
196    /** {@inheritDoc} */
197    public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
198        throws ScmException
199    {
200        HgAddCommand command = new HgAddCommand();
201
202        command.setLogger( getLogger() );
203
204        return (AddScmResult) command.execute( repository, fileSet, parameters );
205    }
206
207    /** {@inheritDoc} */
208    public ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
209                                         CommandParameters parameters )
210        throws ScmException
211    {
212        HgChangeLogCommand command = new HgChangeLogCommand();
213
214        command.setLogger( getLogger() );
215
216        return (ChangeLogScmResult) command.execute( repository, fileSet, parameters );
217    }
218
219    /** {@inheritDoc} */
220    public CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
221                                     CommandParameters parameters )
222        throws ScmException
223    {
224        HgCheckInCommand command = new HgCheckInCommand();
225
226        command.setLogger( getLogger() );
227
228        return (CheckInScmResult) command.execute( repository, fileSet, parameters );
229    }
230
231    /** {@inheritDoc} */
232    public CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
233                                       CommandParameters parameters )
234        throws ScmException
235    {
236        HgCheckOutCommand command = new HgCheckOutCommand();
237
238        command.setLogger( getLogger() );
239
240        return (CheckOutScmResult) command.execute( repository, fileSet, parameters );
241    }
242
243    /** {@inheritDoc} */
244    public TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
245        throws ScmException
246    {
247        HgTagCommand command = new HgTagCommand();
248
249        command.setLogger( getLogger() );
250
251        return (TagScmResult) command.execute( repository, fileSet, parameters );
252    }
253
254    /** {@inheritDoc} */
255    public DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
256        throws ScmException
257    {
258        HgDiffCommand command = new HgDiffCommand();
259
260        command.setLogger( getLogger() );
261
262        return (DiffScmResult) command.execute( repository, fileSet, parameters );
263    }
264
265    /** {@inheritDoc} */
266    public RemoveScmResult remove( ScmProviderRepository repository, ScmFileSet fileSet,
267                                   CommandParameters parameters )
268        throws ScmException
269    {
270        HgRemoveCommand command = new HgRemoveCommand();
271
272        command.setLogger( getLogger() );
273
274        return (RemoveScmResult) command.execute( repository, fileSet, parameters );
275    }
276
277    /** {@inheritDoc} */
278    public StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet,
279                                   CommandParameters parameters )
280        throws ScmException
281    {
282        HgStatusCommand command = new HgStatusCommand();
283
284        command.setLogger( getLogger() );
285
286        return (StatusScmResult) command.execute( repository, fileSet, parameters );
287    }
288
289    /** {@inheritDoc} */
290    public UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet,
291                                   CommandParameters parameters )
292        throws ScmException
293    {
294        HgUpdateCommand command = new HgUpdateCommand();
295
296        command.setLogger( getLogger() );
297
298        return (UpdateScmResult) command.execute( repository, fileSet, parameters );
299    }
300
301    /** {@inheritDoc} */
302    protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet,
303                                    CommandParameters parameters )
304        throws ScmException
305    {
306        HgBlameCommand command = new HgBlameCommand();
307
308        command.setLogger( getLogger() );
309
310        return (BlameScmResult) command.execute( repository, fileSet, parameters );
311    }
312
313    /** {@inheritDoc} */
314    public BranchScmResult branch( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
315        throws ScmException
316    {
317        HgBranchCommand command = new HgBranchCommand();
318
319        command.setLogger( getLogger() );
320
321        return (BranchScmResult) command.execute( repository, fileSet, parameters );
322    }
323
324    /**
325     * @since 1.5
326     */
327    @Override
328    protected ListScmResult list( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
329        throws ScmException
330    {
331        HgListCommand hgListCommand = new HgListCommand();
332        hgListCommand.setLogger( getLogger() );
333        return (ListScmResult) hgListCommand.executeCommand( repository, fileSet, parameters );
334
335    }
336
337    /**
338     * returns result of hg id -i
339     * @since 1.5
340     * @see org.apache.maven.scm.provider.AbstractScmProvider#info(org.apache.maven.scm.provider.ScmProviderRepository, org.apache.maven.scm.ScmFileSet, org.apache.maven.scm.CommandParameters)
341     */
342    @Override
343    public InfoScmResult info( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
344        throws ScmException
345    {
346        HgInfoCommand infoCommand = new HgInfoCommand();
347        infoCommand.setLogger( getLogger() );
348        return (InfoScmResult) infoCommand.execute( repository, fileSet, parameters );
349    }
350}