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.eclipse.aether.internal.impl; 020 021import java.util.function.Function; 022 023import org.eclipse.aether.RepositorySystemSession; 024import org.eclipse.aether.artifact.Artifact; 025import org.eclipse.aether.metadata.Metadata; 026import org.eclipse.aether.repository.ArtifactRepository; 027import org.eclipse.aether.repository.RemoteRepository; 028import org.eclipse.aether.util.ConfigUtils; 029 030/** 031 * Support class for {@link LocalPathPrefixComposerFactory} implementations: it predefines and makes re-usable 032 * common configuration getters, and defines a support class for {@link LocalPathPrefixComposer} carrying same 033 * configuration and providing default implementation for all methods. 034 * <p> 035 * Implementors should extend this class to implement custom split strategies. If one needs to alter default 036 * configuration, they should override any configuration getter from this class. 037 * 038 * @see DefaultLocalPathPrefixComposerFactory 039 * @since 1.8.1 040 */ 041public abstract class LocalPathPrefixComposerFactorySupport implements LocalPathPrefixComposerFactory { 042 043 /** 044 * Whether LRM should split local and remote artifacts. 045 * 046 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 047 * @configurationType {@link java.lang.Boolean} 048 * @configurationDefaultValue {@link #DEFAULT_SPLIT} 049 */ 050 public static final String CONFIG_PROP_SPLIT = EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "split"; 051 052 public static final boolean DEFAULT_SPLIT = false; 053 054 /** 055 * The prefix to use for locally installed artifacts. 056 * 057 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 058 * @configurationType {@link java.lang.String} 059 * @configurationDefaultValue {@link #DEFAULT_LOCAL_PREFIX} 060 */ 061 public static final String CONFIG_PROP_LOCAL_PREFIX = 062 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "localPrefix"; 063 064 public static final String DEFAULT_LOCAL_PREFIX = "installed"; 065 066 /** 067 * Whether locally installed artifacts should be split by version (release/snapshot). 068 * 069 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 070 * @configurationType {@link java.lang.Boolean} 071 * @configurationDefaultValue {@link #DEFAULT_SPLIT_LOCAL} 072 */ 073 public static final String CONFIG_PROP_SPLIT_LOCAL = 074 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitLocal"; 075 076 public static final boolean DEFAULT_SPLIT_LOCAL = false; 077 078 /** 079 * The prefix to use for remotely cached artifacts. 080 * 081 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 082 * @configurationType {@link java.lang.String} 083 * @configurationDefaultValue {@link #DEFAULT_REMOTE_PREFIX} 084 */ 085 public static final String CONFIG_PROP_REMOTE_PREFIX = 086 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "remotePrefix"; 087 088 public static final String DEFAULT_REMOTE_PREFIX = "cached"; 089 090 /** 091 * Whether cached artifacts should be split by version (release/snapshot). 092 * 093 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 094 * @configurationType {@link java.lang.Boolean} 095 * @configurationDefaultValue {@link #DEFAULT_SPLIT_REMOTE} 096 */ 097 public static final String CONFIG_PROP_SPLIT_REMOTE = 098 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitRemote"; 099 100 public static final boolean DEFAULT_SPLIT_REMOTE = false; 101 102 /** 103 * Whether cached artifacts should be split by origin repository (repository ID). 104 * 105 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 106 * @configurationType {@link java.lang.Boolean} 107 * @configurationDefaultValue {@link #DEFAULT_SPLIT_REMOTE_REPOSITORY} 108 */ 109 public static final String CONFIG_PROP_SPLIT_REMOTE_REPOSITORY = 110 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitRemoteRepository"; 111 112 public static final boolean DEFAULT_SPLIT_REMOTE_REPOSITORY = false; 113 114 /** 115 * For cached artifacts, if both splitRemote and splitRemoteRepository are set to true sets the splitting order: 116 * by default it is repositoryId/version (false) or version/repositoryId (true) 117 * 118 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 119 * @configurationType {@link java.lang.Boolean} 120 * @configurationDefaultValue {@link #DEFAULT_SPLIT_REMOTE_REPOSITORY_LAST} 121 */ 122 public static final String CONFIG_PROP_SPLIT_REMOTE_REPOSITORY_LAST = 123 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitRemoteRepositoryLast"; 124 125 public static final boolean DEFAULT_SPLIT_REMOTE_REPOSITORY_LAST = false; 126 127 /** 128 * The prefix to use for release artifacts. 129 * 130 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 131 * @configurationType {@link java.lang.String} 132 * @configurationDefaultValue {@link #DEFAULT_RELEASES_PREFIX} 133 */ 134 public static final String CONFIG_PROP_RELEASES_PREFIX = 135 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "releasesPrefix"; 136 137 public static final String DEFAULT_RELEASES_PREFIX = "releases"; 138 139 /** 140 * The prefix to use for snapshot artifacts. 141 * 142 * @configurationSource {@link RepositorySystemSession#getConfigProperties()} 143 * @configurationType {@link java.lang.String} 144 * @configurationDefaultValue {@link #DEFAULT_SNAPSHOTS_PREFIX} 145 */ 146 public static final String CONFIG_PROP_SNAPSHOTS_PREFIX = 147 EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "snapshotsPrefix"; 148 149 public static final String DEFAULT_SNAPSHOTS_PREFIX = "snapshots"; 150 151 // Legacy support: properties were renamed in Resolver 2.0.x, but we should support 1.9.x properties as well 152 // These below are Resolver 1.9.x properties, are undocumented and shall be removed with Resolver 2.1.x (or later). 153 154 private static final String R1_CONF_PROP_SPLIT = "aether.enhancedLocalRepository.split"; 155 156 private static final String R1_CONF_PROP_LOCAL_PREFIX = "aether.enhancedLocalRepository.localPrefix"; 157 158 private static final String R1_CONF_PROP_SPLIT_LOCAL = "aether.enhancedLocalRepository.splitLocal"; 159 160 private static final String R1_CONF_PROP_REMOTE_PREFIX = "aether.enhancedLocalRepository.remotePrefix"; 161 162 private static final String R1_CONF_PROP_SPLIT_REMOTE = "aether.enhancedLocalRepository.splitRemote"; 163 164 private static final String R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY = 165 "aether.enhancedLocalRepository.splitRemoteRepository"; 166 167 private static final String R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY_LAST = 168 "aether.enhancedLocalRepository.splitRemoteRepositoryLast"; 169 170 private static final String R1_CONF_PROP_RELEASES_PREFIX = "aether.enhancedLocalRepository.releasesPrefix"; 171 172 private static final String R1_CONF_PROP_SNAPSHOTS_PREFIX = "aether.enhancedLocalRepository.snapshotsPrefix"; 173 174 protected boolean isSplit(RepositorySystemSession session) { 175 return ConfigUtils.getBoolean(session, DEFAULT_SPLIT, CONFIG_PROP_SPLIT, R1_CONF_PROP_SPLIT); 176 } 177 178 protected String getLocalPrefix(RepositorySystemSession session) { 179 return ConfigUtils.getString( 180 session, DEFAULT_LOCAL_PREFIX, CONFIG_PROP_LOCAL_PREFIX, R1_CONF_PROP_LOCAL_PREFIX); 181 } 182 183 protected boolean isSplitLocal(RepositorySystemSession session) { 184 return ConfigUtils.getBoolean(session, DEFAULT_SPLIT_LOCAL, CONFIG_PROP_SPLIT_LOCAL, R1_CONF_PROP_SPLIT_LOCAL); 185 } 186 187 protected String getRemotePrefix(RepositorySystemSession session) { 188 return ConfigUtils.getString( 189 session, DEFAULT_REMOTE_PREFIX, CONFIG_PROP_REMOTE_PREFIX, R1_CONF_PROP_REMOTE_PREFIX); 190 } 191 192 protected boolean isSplitRemote(RepositorySystemSession session) { 193 return ConfigUtils.getBoolean( 194 session, DEFAULT_SPLIT_REMOTE, CONFIG_PROP_SPLIT_REMOTE, R1_CONF_PROP_SPLIT_REMOTE); 195 } 196 197 protected boolean isSplitRemoteRepository(RepositorySystemSession session) { 198 return ConfigUtils.getBoolean( 199 session, 200 DEFAULT_SPLIT_REMOTE_REPOSITORY, 201 CONFIG_PROP_SPLIT_REMOTE_REPOSITORY, 202 R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY); 203 } 204 205 protected boolean isSplitRemoteRepositoryLast(RepositorySystemSession session) { 206 return ConfigUtils.getBoolean( 207 session, 208 DEFAULT_SPLIT_REMOTE_REPOSITORY_LAST, 209 CONFIG_PROP_SPLIT_REMOTE_REPOSITORY_LAST, 210 R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY_LAST); 211 } 212 213 protected String getReleasesPrefix(RepositorySystemSession session) { 214 return ConfigUtils.getString( 215 session, DEFAULT_RELEASES_PREFIX, CONFIG_PROP_RELEASES_PREFIX, R1_CONF_PROP_RELEASES_PREFIX); 216 } 217 218 protected String getSnapshotsPrefix(RepositorySystemSession session) { 219 return ConfigUtils.getString( 220 session, DEFAULT_SNAPSHOTS_PREFIX, CONFIG_PROP_SNAPSHOTS_PREFIX, R1_CONF_PROP_SNAPSHOTS_PREFIX); 221 } 222 223 /** 224 * Support class for composers: it defines protected members for all the predefined configuration values and 225 * provides default implementation for methods. Implementors may change it's behaviour by overriding methods. 226 */ 227 @SuppressWarnings("checkstyle:parameternumber") 228 protected abstract static class LocalPathPrefixComposerSupport implements LocalPathPrefixComposer { 229 protected final boolean split; 230 231 protected final String localPrefix; 232 233 protected final boolean splitLocal; 234 235 protected final String remotePrefix; 236 237 protected final boolean splitRemote; 238 239 protected final boolean splitRemoteRepository; 240 241 protected final boolean splitRemoteRepositoryLast; 242 243 protected final String releasesPrefix; 244 245 protected final String snapshotsPrefix; 246 247 protected final Function<ArtifactRepository, String> idToPathSegmentFunction; 248 249 protected LocalPathPrefixComposerSupport( 250 boolean split, 251 String localPrefix, 252 boolean splitLocal, 253 String remotePrefix, 254 boolean splitRemote, 255 boolean splitRemoteRepository, 256 boolean splitRemoteRepositoryLast, 257 String releasesPrefix, 258 String snapshotsPrefix, 259 Function<ArtifactRepository, String> idToPathSegmentFunction) { 260 this.split = split; 261 this.localPrefix = localPrefix; 262 this.splitLocal = splitLocal; 263 this.remotePrefix = remotePrefix; 264 this.splitRemote = splitRemote; 265 this.splitRemoteRepository = splitRemoteRepository; 266 this.splitRemoteRepositoryLast = splitRemoteRepositoryLast; 267 this.releasesPrefix = releasesPrefix; 268 this.snapshotsPrefix = snapshotsPrefix; 269 this.idToPathSegmentFunction = idToPathSegmentFunction; 270 } 271 272 @Override 273 public String getPathPrefixForLocalArtifact(Artifact artifact) { 274 if (!split) { 275 return null; 276 } 277 String result = localPrefix; 278 if (splitLocal) { 279 result += "/" + (artifact.isSnapshot() ? snapshotsPrefix : releasesPrefix); 280 } 281 return result; 282 } 283 284 @Override 285 public String getPathPrefixForRemoteArtifact(Artifact artifact, RemoteRepository repository) { 286 if (!split) { 287 return null; 288 } 289 String result = remotePrefix; 290 if (!splitRemoteRepositoryLast && splitRemoteRepository) { 291 result += "/" + idToPathSegmentFunction.apply(repository); 292 } 293 if (splitRemote) { 294 result += "/" + (artifact.isSnapshot() ? snapshotsPrefix : releasesPrefix); 295 } 296 if (splitRemoteRepositoryLast && splitRemoteRepository) { 297 result += "/" + idToPathSegmentFunction.apply(repository); 298 } 299 return result; 300 } 301 302 @Override 303 public String getPathPrefixForLocalMetadata(Metadata metadata) { 304 if (!split) { 305 return null; 306 } 307 String result = localPrefix; 308 if (splitLocal) { 309 result += "/" + (isSnapshot(metadata) ? snapshotsPrefix : releasesPrefix); 310 } 311 return result; 312 } 313 314 @Override 315 public String getPathPrefixForRemoteMetadata(Metadata metadata, RemoteRepository repository) { 316 if (!split) { 317 return null; 318 } 319 String result = remotePrefix; 320 if (!splitRemoteRepositoryLast && splitRemoteRepository) { 321 result += "/" + idToPathSegmentFunction.apply(repository); 322 } 323 if (splitRemote) { 324 result += "/" + (isSnapshot(metadata) ? snapshotsPrefix : releasesPrefix); 325 } 326 if (splitRemoteRepositoryLast && splitRemoteRepository) { 327 result += "/" + idToPathSegmentFunction.apply(repository); 328 } 329 return result; 330 } 331 332 protected boolean isSnapshot(Metadata metadata) { 333 return !metadata.getVersion().isEmpty() && metadata.getVersion().endsWith("-SNAPSHOT"); 334 } 335 } 336}