001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.maven.scm.provider.svn.repository; 020 021import org.apache.maven.scm.provider.ScmProviderRepository; 022import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost; 023import org.apache.maven.scm.provider.svn.SvnTagBranchUtils; 024 025/** 026 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a> 027 */ 028public class SvnScmProviderRepository extends ScmProviderRepositoryWithHost { 029 private String url; 030 031 private String protocol; 032 033 /** 034 * The base directory for any tags. Can be relative to the repository URL or an absolute URL. 035 */ 036 private String tagBase; 037 038 /** 039 * The base directory for any branches. Can be relative to the repository URL or an absolute URL. 040 */ 041 private String branchBase; 042 043 public SvnScmProviderRepository(String url) { 044 parseUrl(url); 045 046 tagBase = SvnTagBranchUtils.resolveTagBase(url); 047 048 branchBase = SvnTagBranchUtils.resolveBranchBase(url); 049 } 050 051 public SvnScmProviderRepository(String url, String user, String password) { 052 this(url); 053 054 setUser(user); 055 056 setPassword(password); 057 } 058 059 public String getUrl() { 060 return url; 061 } 062 063 /** 064 * Returns the url/directory to be used when tagging this repository. 065 */ 066 public String getTagBase() { 067 return tagBase; 068 } 069 070 /** 071 * Sets the url/directory to be used when tagging this repository. 072 * The TagBase is a way to override the default tag location for the 073 * repository. The default tag location is automatically determined 074 * for repositories in the standard subversion layout (with /tags /branches /trunk). 075 * Specify this value only if the repository is using a directory other than "/tags" for tagging. 076 * 077 * @param tagBase an absolute or relative url to the base directory to create tags in. 078 * URL should be in a format that svn client understands, not the scm url format. 079 */ 080 public void setTagBase(String tagBase) { 081 this.tagBase = tagBase; 082 } 083 084 /** 085 * Returns the url/directory to be used when tagging this repository. 086 */ 087 public String getBranchBase() { 088 return branchBase; 089 } 090 091 /** 092 * Sets the url/directory to be used when branching this repository. 093 * The BranchBase is a way to override the default branch location for the 094 * repository. The default branch location is automatically determined 095 * for repositories in the standard subversion layout (with /tags /branches /trunk). 096 * Specify this value only if the repository is using a directory other than "/branches" for branching. 097 * 098 * @param branchBase an absolute or relative url to the base directory to create branch in. 099 * URL should be in a format that svn client understands, not the scm url format. 100 */ 101 public void setBranchBase(String branchBase) { 102 this.branchBase = branchBase; 103 } 104 105 private void setProtocol(String protocol) { 106 this.protocol = protocol; 107 } 108 109 /** 110 * Get the protocol used in this repository (file://, http://, https://,...) 111 * 112 * @return the protocol 113 */ 114 public String getProtocol() { 115 return protocol; 116 } 117 118 private void parseUrl(String url) { 119 if (url.startsWith("file")) { 120 setProtocol("file://"); 121 } else if (url.startsWith("https")) { 122 setProtocol("https://"); 123 } else if (url.startsWith("http")) { 124 setProtocol("http://"); 125 } else if (url.startsWith("svn+")) { 126 setProtocol(url.substring(0, url.indexOf("://") + 3)); 127 } else if (url.startsWith("svn")) { 128 setProtocol("svn://"); 129 } 130 131 if (getProtocol() == null) { 132 return; 133 } 134 135 String urlPath = url.substring(getProtocol().length()); 136 137 int indexAt = urlPath.indexOf('@'); 138 139 // a file:// URL may contain userinfo according to RFC 8089, but our implementation is broken 140 // extract user information, broken see SCM-909 141 if (indexAt > 0 && !getProtocol().startsWith("svn+") && !getProtocol().equals("file://")) { 142 String userPassword = urlPath.substring(0, indexAt); 143 if (userPassword.indexOf(':') < 0) { 144 setUser(userPassword); 145 } else { 146 setUser(userPassword.substring(0, userPassword.indexOf(':'))); 147 setPassword(userPassword.substring(userPassword.indexOf(':') + 1)); 148 } 149 150 urlPath = urlPath.substring(indexAt + 1); 151 152 this.url = getProtocol() + urlPath; 153 } else { 154 this.url = getProtocol() + urlPath; 155 } 156 157 if (!"file://".equals(getProtocol())) { 158 int indexSlash = urlPath.indexOf('/'); 159 160 String hostPort = urlPath; 161 162 if (indexSlash > 0) { 163 hostPort = urlPath.substring(0, indexSlash); 164 } 165 166 int indexColon = hostPort.indexOf(':'); 167 168 if (indexColon > 0) { 169 setHost(hostPort.substring(0, indexColon)); 170 setPort(Integer.parseInt(hostPort.substring(indexColon + 1))); 171 } else { 172 setHost(hostPort); 173 } 174 } 175 } 176 177 /** 178 * {@inheritDoc} 179 */ 180 public ScmProviderRepository getParent() { 181 String newUrl = getUrl().substring(getProtocol().length()); 182 183 while (newUrl.endsWith("/.")) { 184 newUrl = newUrl.substring(0, newUrl.length() - 2); 185 } 186 187 while (newUrl.endsWith("/")) { 188 newUrl = newUrl.substring(0, newUrl.length() - 1); 189 } 190 191 int i = newUrl.lastIndexOf('/'); 192 193 if (i < 0) { 194 return null; 195 } 196 newUrl = newUrl.substring(0, i); 197 198 return new SvnScmProviderRepository(getProtocol() + newUrl, getUser(), getPassword()); 199 } 200 201 /** 202 * {@inheritDoc} 203 */ 204 public String getRelativePath(ScmProviderRepository ancestor) { 205 if (ancestor instanceof SvnScmProviderRepository) { 206 SvnScmProviderRepository svnAncestor = (SvnScmProviderRepository) ancestor; 207 208 String path = getUrl().replaceFirst(svnAncestor.getUrl() + "/", ""); 209 210 if (!path.equals(getUrl())) { 211 return path; 212 } 213 } 214 return null; 215 } 216 217 /** 218 * {@inheritDoc} 219 */ 220 public String toString() { 221 return getUrl(); 222 } 223}