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 || !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}