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