001    package 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    
022    import java.net.URI;
023    
024    import org.apache.maven.scm.CommandParameters;
025    import org.apache.maven.scm.ScmException;
026    import org.apache.maven.scm.ScmFileSet;
027    import org.apache.maven.scm.command.add.AddScmResult;
028    import org.apache.maven.scm.command.blame.BlameScmResult;
029    import org.apache.maven.scm.command.branch.BranchScmResult;
030    import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
031    import org.apache.maven.scm.command.checkin.CheckInScmResult;
032    import org.apache.maven.scm.command.checkout.CheckOutScmResult;
033    import org.apache.maven.scm.command.diff.DiffScmResult;
034    import org.apache.maven.scm.command.edit.EditScmResult;
035    import org.apache.maven.scm.command.export.ExportScmResult;
036    import org.apache.maven.scm.command.list.ListScmResult;
037    import org.apache.maven.scm.command.status.StatusScmResult;
038    import org.apache.maven.scm.command.tag.TagScmResult;
039    import org.apache.maven.scm.command.unedit.UnEditScmResult;
040    import org.apache.maven.scm.command.update.UpdateScmResult;
041    import org.apache.maven.scm.provider.AbstractScmProvider;
042    import org.apache.maven.scm.provider.ScmProviderRepository;
043    import org.apache.maven.scm.provider.tfs.command.TfsAddCommand;
044    import org.apache.maven.scm.provider.tfs.command.TfsBranchCommand;
045    import org.apache.maven.scm.provider.tfs.command.TfsChangeLogCommand;
046    import org.apache.maven.scm.provider.tfs.command.TfsCheckInCommand;
047    import org.apache.maven.scm.provider.tfs.command.TfsCheckOutCommand;
048    import org.apache.maven.scm.provider.tfs.command.TfsEditCommand;
049    import org.apache.maven.scm.provider.tfs.command.TfsListCommand;
050    import org.apache.maven.scm.provider.tfs.command.TfsStatusCommand;
051    import org.apache.maven.scm.provider.tfs.command.TfsTagCommand;
052    import org.apache.maven.scm.provider.tfs.command.TfsUnEditCommand;
053    import org.apache.maven.scm.provider.tfs.command.TfsUpdateCommand;
054    import org.apache.maven.scm.provider.tfs.command.blame.TfsBlameCommand;
055    import org.apache.maven.scm.repository.ScmRepositoryException;
056    
057    /**
058     * @plexus.component role="org.apache.maven.scm.provider.ScmProvider" role-hint="tfs"
059     */
060    public 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    }