1 package org.apache.maven.scm.provider.svn.repository;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import org.apache.maven.scm.provider.ScmProviderRepository;
23 import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost;
24 import org.apache.maven.scm.provider.svn.SvnTagBranchUtils;
25
26 /**
27 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
28 *
29 */
30 public class SvnScmProviderRepository
31 extends ScmProviderRepositoryWithHost
32 {
33 /** */
34 private String url;
35
36 private String protocol;
37
38 /**
39 * The base directory for any tags. Can be relative to the repository URL or an absolute URL.
40 */
41 private String tagBase;
42
43 /**
44 * The base directory for any branches. Can be relative to the repository URL or an absolute URL.
45 */
46 private String branchBase;
47
48 public SvnScmProviderRepository( String url )
49 {
50 parseUrl( url );
51
52 tagBase = SvnTagBranchUtils.resolveTagBase( url );
53
54 branchBase = SvnTagBranchUtils.resolveBranchBase( url );
55 }
56
57 public SvnScmProviderRepository( String url, String user, String password )
58 {
59 this( url );
60
61 setUser( user );
62
63 setPassword( password );
64 }
65
66 public String getUrl()
67 {
68 return url;
69 }
70
71 /**
72 * Returns the url/directory to be used when tagging this repository.
73 */
74 public String getTagBase()
75 {
76 return tagBase;
77 }
78
79 /**
80 * Sets the url/directory to be used when tagging this repository.
81 * The TagBase is a way to override the default tag location for the
82 * repository. The default tag location is automatically determined
83 * for repositories in the standard subversion layout (with /tags /branches /trunk).
84 * Specify this value only if the repository is using a directory other than "/tags" for tagging.
85 *
86 * @param tagBase an absolute or relative url to the base directory to create tags in.
87 * URL should be in a format that svn client understands, not the scm url format.
88 */
89 public void setTagBase( String tagBase )
90 {
91 this.tagBase = tagBase;
92 }
93
94 /**
95 * Returns the url/directory to be used when tagging this repository.
96 */
97 public String getBranchBase()
98 {
99 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 // a file:// URL may contain userinfo according to RFC 8089, but our implementation is broken
165 // extract user information, broken see SCM-909
166 if ( indexAt > 0 && !getProtocol().startsWith( "svn+" ) && !getProtocol().equals( "file://" ) )
167 {
168 String userPassword = urlPath.substring( 0, indexAt );
169 if ( userPassword.indexOf( ':' ) < 0 )
170 {
171 setUser( userPassword );
172 }
173 else
174 {
175 setUser( userPassword.substring( 0, userPassword.indexOf( ':' ) ) );
176 setPassword( userPassword.substring( userPassword.indexOf( ':' ) + 1 ) );
177 }
178
179 urlPath = urlPath.substring( indexAt + 1 );
180
181 this.url = getProtocol() + urlPath;
182 }
183 else
184 {
185 this.url = getProtocol() + urlPath;
186 }
187
188 if ( !"file://".equals( getProtocol() ) )
189 {
190 int indexSlash = urlPath.indexOf( '/' );
191
192 String hostPort = urlPath;
193
194 if ( indexSlash > 0 )
195 {
196 hostPort = urlPath.substring( 0, indexSlash );
197 }
198
199 int indexColon = hostPort.indexOf( ':' );
200
201 if ( indexColon > 0 )
202 {
203 setHost( hostPort.substring( 0, indexColon ) );
204 setPort( Integer.parseInt( hostPort.substring( indexColon + 1 ) ) );
205 }
206 else
207 {
208 setHost( hostPort );
209 }
210 }
211 }
212
213 /** {@inheritDoc} */
214 public ScmProviderRepository getParent()
215 {
216 String newUrl = getUrl().substring( getProtocol().length() );
217
218 while ( newUrl.endsWith( "/." ) )
219 {
220 newUrl = newUrl.substring( 0, newUrl.length() - 2 );
221 }
222
223 while ( newUrl.endsWith( "/" ) )
224 {
225 newUrl = newUrl.substring( 0, newUrl.length() - 1 );
226 }
227
228 int i = newUrl.lastIndexOf( '/' );
229
230 if ( i < 0 )
231 {
232 return null;
233 }
234 newUrl = newUrl.substring( 0, i );
235
236 return new SvnScmProviderRepository( getProtocol() + newUrl, getUser(), getPassword() );
237 }
238
239 /** {@inheritDoc} */
240 public String getRelativePath( ScmProviderRepository ancestor )
241 {
242 if ( ancestor instanceof SvnScmProviderRepository )
243 {
244 SvnScmProviderRepository svnAncestor = (SvnScmProviderRepository) ancestor;
245
246 String path = getUrl().replaceFirst( svnAncestor.getUrl() + "/", "" );
247
248 if ( !path.equals( getUrl() ) )
249 {
250 return path;
251 }
252 }
253 return null;
254 }
255
256 /** {@inheritDoc} */
257 public String toString()
258 {
259 return getUrl();
260 }
261
262 }