001package org.apache.maven.scm.provider.svn.repository;
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 org.apache.maven.scm.provider.ScmProviderRepository;
023import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
024import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
025
026/**
027 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
028 *
029 */
030public class SvnScmProviderRepository
031    extends ScmProviderRepositoryWithHost
032{
033    /** */
034    private String url;
035
036    private String protocol;
037
038    /**
039     * The base directory for any tags. Can be relative to the repository URL or an absolute URL.
040     */
041    private String tagBase;
042
043    /**
044     * The base directory for any branches. Can be relative to the repository URL or an absolute URL.
045     */
046    private String branchBase;
047
048    public SvnScmProviderRepository( String url )
049    {
050        parseUrl( url );
051
052        tagBase = SvnTagBranchUtils.resolveTagBase( url );
053
054        branchBase = SvnTagBranchUtils.resolveBranchBase( url );
055    }
056
057    public SvnScmProviderRepository( String url, String user, String password )
058    {
059        this( url );
060
061        setUser( user );
062
063        setPassword( password );
064    }
065
066    public String getUrl()
067    {
068        return url;
069    }
070
071    /**
072     * Returns the url/directory to be used when tagging this repository.
073     */
074    public String getTagBase()
075    {
076        return tagBase;
077    }
078
079    /**
080     * Sets the url/directory to be used when tagging this repository.
081     * The TagBase is a way to override the default tag location for the
082     * repository.  The default tag location is automatically determined
083     * for repositories in the standard subversion layout (with /tags /branches /trunk).
084     * Specify this value only if the repository is using a directory other than "/tags" for tagging.
085     *
086     * @param tagBase an absolute or relative url to the base directory to create tags in.
087     *                URL should be in a format that svn client understands, not the scm url format.
088     */
089    public void setTagBase( String tagBase )
090    {
091        this.tagBase = tagBase;
092    }
093
094    /**
095     * Returns the url/directory to be used when tagging this repository.
096     */
097    public String getBranchBase()
098    {
099        return branchBase;
100    }
101
102    /**
103     * Sets the url/directory to be used when branching this repository.
104     * The BranchBase is a way to override the default branch location for the
105     * repository.  The default branch location is automatically determined
106     * for repositories in the standard subversion layout (with /tags /branches /trunk).
107     * Specify this value only if the repository is using a directory other than "/branches" for branching.
108     *
109     * @param branchBase an absolute or relative url to the base directory to create branch in.
110     *                   URL should be in a format that svn client understands, not the scm url format.
111     */
112    public void setBranchBase( String branchBase )
113    {
114        this.branchBase = branchBase;
115    }
116
117    private void setProtocol( String protocol )
118    {
119        this.protocol = protocol;
120    }
121
122    /**
123     * Get the protocol used in this repository (file://, http://, https://,...)
124     *
125     * @return the protocol
126     */
127    public String getProtocol()
128    {
129        return protocol;
130    }
131
132    private void parseUrl( String url )
133    {
134        if ( url.startsWith( "file" ) )
135        {
136            setProtocol( "file://" );
137        }
138        else if ( url.startsWith( "https" ) )
139        {
140            setProtocol( "https://" );
141        }
142        else if ( url.startsWith( "http" ) )
143        {
144            setProtocol( "http://" );
145        }
146        else if ( url.startsWith( "svn+" ) )
147        {
148            setProtocol( url.substring( 0, url.indexOf( "://" ) + 3 ) );
149        }
150        else if ( url.startsWith( "svn" ) )
151        {
152            setProtocol( "svn://" );
153        }
154
155        if ( getProtocol() == null )
156        {
157            return;
158        }
159
160        String urlPath = url.substring( getProtocol().length() );
161
162        int indexAt = urlPath.indexOf( '@' );
163
164        if ( indexAt > 0 && !getProtocol().startsWith( "svn+" ) )
165        {
166            String userPassword = urlPath.substring( 0, indexAt );
167            if ( userPassword.indexOf( ':' ) < 0 )
168            {
169                setUser( userPassword );
170            }
171            else
172            {
173                setUser( userPassword.substring( 0, userPassword.indexOf( ':' ) ) );
174                setPassword( userPassword.substring( userPassword.indexOf( ':' ) + 1 ) );
175            }
176
177            urlPath = urlPath.substring( indexAt + 1 );
178
179            this.url = getProtocol() + urlPath;
180        }
181        else
182        {
183            this.url = getProtocol() + urlPath;
184        }
185
186        if ( !"file://".equals( getProtocol() ) )
187        {
188            int indexSlash = urlPath.indexOf( '/' );
189
190            String hostPort = urlPath;
191
192            if ( indexSlash > 0 )
193            {
194                hostPort = urlPath.substring( 0, indexSlash );
195            }
196
197            int indexColon = hostPort.indexOf( ':' );
198
199            if ( indexColon > 0 )
200            {
201                setHost( hostPort.substring( 0, indexColon ) );
202                setPort( Integer.parseInt( hostPort.substring( indexColon + 1 ) ) );
203            }
204            else
205            {
206                setHost( hostPort );
207            }
208        }
209    }
210
211    /** {@inheritDoc} */
212    public ScmProviderRepository getParent()
213    {
214        String newUrl = getUrl().substring( getProtocol().length() );
215
216        while ( newUrl.endsWith( "/." ) )
217        {
218            newUrl = newUrl.substring( 0, newUrl.length() - 2 );
219        }
220
221        while ( newUrl.endsWith( "/" ) )
222        {
223            newUrl = newUrl.substring( 0, newUrl.length() - 1 );
224        }
225
226        int i = newUrl.lastIndexOf( '/' );
227
228        if ( i < 0 )
229        {
230            return null;
231        }
232        newUrl = newUrl.substring( 0, i );
233
234        return new SvnScmProviderRepository( getProtocol() + newUrl, getUser(), getPassword() );
235    }
236
237    /** {@inheritDoc} */
238    public String getRelativePath( ScmProviderRepository ancestor )
239    {
240        if ( ancestor instanceof SvnScmProviderRepository )
241        {
242            SvnScmProviderRepository svnAncestor = (SvnScmProviderRepository) ancestor;
243
244            String path = getUrl().replaceFirst( svnAncestor.getUrl() + "/", "" );
245
246            if ( !path.equals( getUrl() ) )
247            {
248                return path;
249            }
250        }
251        return null;
252    }
253
254    /** {@inheritDoc} */
255    public String toString()
256    {
257        return getUrl();
258    }
259
260}