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 * 028 */ 029public class SvnScmProviderRepository extends ScmProviderRepositoryWithHost { 030 /** */ 031 private String url; 032 033 private String protocol; 034 035 /** 036 * The base directory for any tags. Can be relative to the repository URL or an absolute URL. 037 */ 038 private String tagBase; 039 040 /** 041 * The base directory for any branches. Can be relative to the repository URL or an absolute URL. 042 */ 043 private String branchBase; 044 045 public SvnScmProviderRepository(String url) { 046 parseUrl(url); 047 048 tagBase = SvnTagBranchUtils.resolveTagBase(url); 049 050 branchBase = SvnTagBranchUtils.resolveBranchBase(url); 051 } 052 053 public SvnScmProviderRepository(String url, String user, String password) { 054 this(url); 055 056 setUser(user); 057 058 setPassword(password); 059 } 060 061 public String getUrl() { 062 return url; 063 } 064 065 /** 066 * Returns the url/directory to be used when tagging this repository. 067 */ 068 public String getTagBase() { 069 return tagBase; 070 } 071 072 /** 073 * Sets the url/directory to be used when tagging this repository. 074 * The TagBase is a way to override the default tag location for the 075 * repository. The default tag location is automatically determined 076 * for repositories in the standard subversion layout (with /tags /branches /trunk). 077 * Specify this value only if the repository is using a directory other than "/tags" for tagging. 078 * 079 * @param tagBase an absolute or relative url to the base directory to create tags in. 080 * URL should be in a format that svn client understands, not the scm url format. 081 */ 082 public void setTagBase(String tagBase) { 083 this.tagBase = tagBase; 084 } 085 086 /** 087 * Returns the url/directory to be used when tagging this repository. 088 */ 089 public String getBranchBase() { 090 return branchBase; 091 } 092 093 /** 094 * Sets the url/directory to be used when branching this repository. 095 * The BranchBase is a way to override the default branch location for the 096 * repository. The default branch location is automatically determined 097 * for repositories in the standard subversion layout (with /tags /branches /trunk). 098 * Specify this value only if the repository is using a directory other than "/branches" for branching. 099 * 100 * @param branchBase an absolute or relative url to the base directory to create branch in. 101 * URL should be in a format that svn client understands, not the scm url format. 102 */ 103 public void setBranchBase(String branchBase) { 104 this.branchBase = branchBase; 105 } 106 107 private void setProtocol(String protocol) { 108 this.protocol = protocol; 109 } 110 111 /** 112 * Get the protocol used in this repository (file://, http://, https://,...) 113 * 114 * @return the protocol 115 */ 116 public String getProtocol() { 117 return protocol; 118 } 119 120 private void parseUrl(String url) { 121 if (url.startsWith("file")) { 122 setProtocol("file://"); 123 } else if (url.startsWith("https")) { 124 setProtocol("https://"); 125 } else if (url.startsWith("http")) { 126 setProtocol("http://"); 127 } else if (url.startsWith("svn+")) { 128 setProtocol(url.substring(0, url.indexOf("://") + 3)); 129 } else if (url.startsWith("svn")) { 130 setProtocol("svn://"); 131 } 132 133 if (getProtocol() == null) { 134 return; 135 } 136 137 String urlPath = url.substring(getProtocol().length()); 138 139 int indexAt = urlPath.indexOf('@'); 140 141 // a file:// URL may contain userinfo according to RFC 8089, but our implementation is broken 142 // extract user information, broken see SCM-909 143 if (indexAt > 0 && !getProtocol().startsWith("svn+") && !getProtocol().equals("file://")) { 144 String userPassword = urlPath.substring(0, indexAt); 145 if (userPassword.indexOf(':') < 0) { 146 setUser(userPassword); 147 } else { 148 setUser(userPassword.substring(0, userPassword.indexOf(':'))); 149 setPassword(userPassword.substring(userPassword.indexOf(':') + 1)); 150 } 151 152 urlPath = urlPath.substring(indexAt + 1); 153 154 this.url = getProtocol() + urlPath; 155 } else { 156 this.url = getProtocol() + urlPath; 157 } 158 159 if (!"file://".equals(getProtocol())) { 160 int indexSlash = urlPath.indexOf('/'); 161 162 String hostPort = urlPath; 163 164 if (indexSlash > 0) { 165 hostPort = urlPath.substring(0, indexSlash); 166 } 167 168 int indexColon = hostPort.indexOf(':'); 169 170 if (indexColon > 0) { 171 setHost(hostPort.substring(0, indexColon)); 172 setPort(Integer.parseInt(hostPort.substring(indexColon + 1))); 173 } else { 174 setHost(hostPort); 175 } 176 } 177 } 178 179 /** {@inheritDoc} */ 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 /** {@inheritDoc} */ 202 public String getRelativePath(ScmProviderRepository ancestor) { 203 if (ancestor instanceof SvnScmProviderRepository) { 204 SvnScmProviderRepository svnAncestor = (SvnScmProviderRepository) ancestor; 205 206 String path = getUrl().replaceFirst(svnAncestor.getUrl() + "/", ""); 207 208 if (!path.equals(getUrl())) { 209 return path; 210 } 211 } 212 return null; 213 } 214 215 /** {@inheritDoc} */ 216 public String toString() { 217 return getUrl(); 218 } 219}