001    package 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    
022    import org.apache.maven.scm.provider.ScmProviderRepository;
023    import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
024    import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
025    
026    /**
027     * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
028     *
029     */
030    public 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    }