001package org.apache.maven.scm.provider.tfs;
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.net.URI;
023
024import org.apache.maven.scm.CommandParameters;
025import org.apache.maven.scm.ScmException;
026import org.apache.maven.scm.ScmFileSet;
027import org.apache.maven.scm.command.add.AddScmResult;
028import org.apache.maven.scm.command.blame.BlameScmResult;
029import org.apache.maven.scm.command.branch.BranchScmResult;
030import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
031import org.apache.maven.scm.command.checkin.CheckInScmResult;
032import org.apache.maven.scm.command.checkout.CheckOutScmResult;
033import org.apache.maven.scm.command.diff.DiffScmResult;
034import org.apache.maven.scm.command.edit.EditScmResult;
035import org.apache.maven.scm.command.export.ExportScmResult;
036import org.apache.maven.scm.command.list.ListScmResult;
037import org.apache.maven.scm.command.status.StatusScmResult;
038import org.apache.maven.scm.command.tag.TagScmResult;
039import org.apache.maven.scm.command.unedit.UnEditScmResult;
040import org.apache.maven.scm.command.update.UpdateScmResult;
041import org.apache.maven.scm.provider.AbstractScmProvider;
042import org.apache.maven.scm.provider.ScmProviderRepository;
043import org.apache.maven.scm.provider.tfs.command.TfsAddCommand;
044import org.apache.maven.scm.provider.tfs.command.TfsBranchCommand;
045import org.apache.maven.scm.provider.tfs.command.TfsChangeLogCommand;
046import org.apache.maven.scm.provider.tfs.command.TfsCheckInCommand;
047import org.apache.maven.scm.provider.tfs.command.TfsCheckOutCommand;
048import org.apache.maven.scm.provider.tfs.command.TfsEditCommand;
049import org.apache.maven.scm.provider.tfs.command.TfsListCommand;
050import org.apache.maven.scm.provider.tfs.command.TfsStatusCommand;
051import org.apache.maven.scm.provider.tfs.command.TfsTagCommand;
052import org.apache.maven.scm.provider.tfs.command.TfsUnEditCommand;
053import org.apache.maven.scm.provider.tfs.command.TfsUpdateCommand;
054import org.apache.maven.scm.provider.tfs.command.blame.TfsBlameCommand;
055import org.apache.maven.scm.repository.ScmRepositoryException;
056
057/**
058 * @plexus.component role="org.apache.maven.scm.provider.ScmProvider" role-hint="tfs"
059 */
060public class TfsScmProvider
061    extends AbstractScmProvider
062{
063
064    public static final String TFS_URL_FORMAT =
065        "[[domain\\]username[;password]@]http[s]://server_name[:port]:workspace:$/TeamProject/Path/To/Project";
066
067    // ----------------------------------------------------------------------
068    // ScmProvider Implementation
069    // ----------------------------------------------------------------------
070
071    public String getScmType()
072    {
073        return "tfs";
074    }
075
076    public ScmProviderRepository makeProviderScmRepository( String scmUrl, char delimiter )
077        throws ScmRepositoryException
078    {
079        // Look for the TFS URL after any '@' delmiter used to pass
080        // usernames/password etc
081        // We deliberately look for the last '@' character as username could
082        // contain an '@' also.
083        int lastAtPos = scmUrl.lastIndexOf( '@' );
084        getLogger().info( "scmUrl - " + scmUrl );
085
086        String tfsUrl = ( lastAtPos < 0 ) ? scmUrl : scmUrl.substring( lastAtPos + 1 );
087        String usernamePassword = ( lastAtPos < 0 ) ? null : scmUrl.substring( 0, lastAtPos );
088
089        // Look for TFS path after the end of the TFS URL
090        int tfsPathPos = tfsUrl.lastIndexOf( delimiter + "$/" );
091        String serverPath = "$/";
092        if ( tfsPathPos > 0 )
093        {
094            serverPath = tfsUrl.substring( tfsPathPos + 1 );
095            tfsUrl = tfsUrl.substring( 0, tfsPathPos );
096        }
097
098        // Look for workspace ater the end of the TFS URL
099        int workspacePos = tfsUrl.lastIndexOf( delimiter );
100        String workspace = tfsUrl.substring( workspacePos + 1 );
101        tfsUrl = tfsUrl.substring( 0, workspacePos );
102
103        try
104        {
105            // Use URI's validation to determine if valid URI.
106            URI tfsUri = URI.create( tfsUrl );
107            String scheme = tfsUri.getScheme();
108            getLogger().info( "Scheme - " + scheme );
109            if ( scheme == null || !( scheme.equalsIgnoreCase( "http" ) || scheme.equalsIgnoreCase( "https" ) ) )
110            {
111                throw new ScmRepositoryException( "TFS Url \"" + tfsUrl + "\" is not a valid URL. "
112                    + "The TFS Url syntax is " + TFS_URL_FORMAT );
113            }
114        }
115        catch ( IllegalArgumentException e )
116        {
117            throw new ScmRepositoryException( "TFS Url \"" + tfsUrl + "\" is not a valid URL. The TFS Url syntax is "
118                + TFS_URL_FORMAT );
119        }
120
121        String username = null;
122        String password = null;
123
124        if ( usernamePassword != null )
125        {
126            // Deliberately not using .split here in case password contains a
127            // ';'
128            int delimPos = usernamePassword.indexOf( ';' );
129            username = ( delimPos < 0 ) ? usernamePassword : usernamePassword.substring( 0, delimPos );
130            password = ( delimPos < 0 ) ? null : usernamePassword.substring( delimPos + 1 );
131        }
132
133        return new TfsScmProviderRepository( tfsUrl, username, password, serverPath, workspace );
134    }
135
136    protected ChangeLogScmResult changelog( ScmProviderRepository repository, ScmFileSet fileSet,
137                                            CommandParameters parameters )
138        throws ScmException
139    {
140        TfsChangeLogCommand command = new TfsChangeLogCommand();
141        command.setLogger( getLogger() );
142        return (ChangeLogScmResult) command.execute( repository, fileSet, parameters );
143    }
144
145    protected CheckOutScmResult checkout( ScmProviderRepository repository, ScmFileSet fileSet,
146                                          CommandParameters parameters )
147        throws ScmException
148    {
149        TfsCheckOutCommand command = new TfsCheckOutCommand();
150        command.setLogger( getLogger() );
151        return (CheckOutScmResult) command.execute( repository, fileSet, parameters );
152    }
153
154    protected EditScmResult edit( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
155        throws ScmException
156    {
157        TfsEditCommand command = new TfsEditCommand();
158        command.setLogger( getLogger() );
159        return (EditScmResult) command.execute( repository, fileSet, parameters );
160    }
161
162    protected UnEditScmResult unedit( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
163        throws ScmException
164    {
165        TfsUnEditCommand command = new TfsUnEditCommand();
166        command.setLogger( getLogger() );
167        return (UnEditScmResult) command.execute( repository, fileSet, parameters );
168    }
169
170    protected StatusScmResult status( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
171        throws ScmException
172    {
173        TfsStatusCommand command = new TfsStatusCommand();
174        command.setLogger( getLogger() );
175        return (StatusScmResult) command.execute( repository, fileSet, parameters );
176    }
177
178    protected UpdateScmResult update( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
179        throws ScmException
180    {
181        TfsUpdateCommand command = new TfsUpdateCommand();
182        command.setLogger( getLogger() );
183        return (UpdateScmResult) command.execute( repository, fileSet, parameters );
184    }
185
186    protected CheckInScmResult checkin( ScmProviderRepository repository, ScmFileSet fileSet,
187                                        CommandParameters parameters )
188        throws ScmException
189    {
190        TfsCheckInCommand command = new TfsCheckInCommand();
191        command.setLogger( getLogger() );
192        return (CheckInScmResult) command.execute( repository, fileSet, parameters );
193    }
194
195    public AddScmResult add( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
196        throws ScmException
197    {
198        TfsAddCommand command = new TfsAddCommand();
199        command.setLogger( getLogger() );
200        return (AddScmResult) command.execute( repository, fileSet, parameters );
201    }
202
203    protected TagScmResult tag( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
204        throws ScmException
205    {
206        TfsTagCommand command = new TfsTagCommand();
207        command.setLogger( getLogger() );
208        return (TagScmResult) command.execute( repository, fileSet, parameters );
209    }
210
211    protected BranchScmResult branch( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
212        throws ScmException
213    {
214        TfsBranchCommand command = new TfsBranchCommand();
215        command.setLogger( getLogger() );
216        return (BranchScmResult) command.execute( repository, fileSet, parameters );
217    }
218
219    protected ListScmResult list( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
220        throws ScmException
221    {
222        TfsListCommand command = new TfsListCommand();
223        command.setLogger( getLogger() );
224        return (ListScmResult) command.execute( repository, fileSet, parameters );
225    }
226
227    protected BlameScmResult blame( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
228        throws ScmException
229    {
230        TfsBlameCommand command = new TfsBlameCommand();
231        command.setLogger( getLogger() );
232        return (BlameScmResult) command.execute( repository, fileSet, parameters );
233    }
234
235    protected DiffScmResult diff( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
236        throws ScmException
237    {
238        // Because tf launches only external diffs
239        return super.diff( repository, fileSet, parameters );
240    }
241
242    protected ExportScmResult export( ScmProviderRepository repository, ScmFileSet fileSet, CommandParameters parameters )
243        throws ScmException
244    {
245        // Use checkout instead
246        return super.export( repository, fileSet, parameters );
247    }
248
249}