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 // 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}