View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl;
20  
21  import java.util.function.Function;
22  
23  import org.eclipse.aether.RepositorySystemSession;
24  import org.eclipse.aether.artifact.Artifact;
25  import org.eclipse.aether.metadata.Metadata;
26  import org.eclipse.aether.repository.ArtifactRepository;
27  import org.eclipse.aether.repository.RemoteRepository;
28  import org.eclipse.aether.util.ConfigUtils;
29  
30  /**
31   * Support class for {@link LocalPathPrefixComposerFactory} implementations: it predefines and makes re-usable
32   * common configuration getters, and defines a support class for {@link LocalPathPrefixComposer} carrying same
33   * configuration and providing default implementation for all methods.
34   * <p>
35   * Implementors should extend this class to implement custom split strategies. If one needs to alter default
36   * configuration, they should override any configuration getter from this class.
37   *
38   * @see DefaultLocalPathPrefixComposerFactory
39   * @since 1.8.1
40   */
41  public abstract class LocalPathPrefixComposerFactorySupport implements LocalPathPrefixComposerFactory {
42  
43      /**
44       * Whether LRM should split local and remote artifacts.
45       *
46       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
47       * @configurationType {@link java.lang.Boolean}
48       * @configurationDefaultValue {@link #DEFAULT_SPLIT}
49       */
50      public static final String CONFIG_PROP_SPLIT = EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "split";
51  
52      public static final boolean DEFAULT_SPLIT = false;
53  
54      /**
55       * The prefix to use for locally installed artifacts.
56       *
57       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
58       * @configurationType {@link java.lang.String}
59       * @configurationDefaultValue {@link #DEFAULT_LOCAL_PREFIX}
60       */
61      public static final String CONFIG_PROP_LOCAL_PREFIX =
62              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "localPrefix";
63  
64      public static final String DEFAULT_LOCAL_PREFIX = "installed";
65  
66      /**
67       * Whether locally installed artifacts should be split by version (release/snapshot).
68       *
69       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
70       * @configurationType {@link java.lang.Boolean}
71       * @configurationDefaultValue {@link #DEFAULT_SPLIT_LOCAL}
72       */
73      public static final String CONFIG_PROP_SPLIT_LOCAL =
74              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitLocal";
75  
76      public static final boolean DEFAULT_SPLIT_LOCAL = false;
77  
78      /**
79       * The prefix to use for remotely cached artifacts.
80       *
81       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
82       * @configurationType {@link java.lang.String}
83       * @configurationDefaultValue {@link #DEFAULT_REMOTE_PREFIX}
84       */
85      public static final String CONFIG_PROP_REMOTE_PREFIX =
86              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "remotePrefix";
87  
88      public static final String DEFAULT_REMOTE_PREFIX = "cached";
89  
90      /**
91       * Whether cached artifacts should be split by version (release/snapshot).
92       *
93       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
94       * @configurationType {@link java.lang.Boolean}
95       * @configurationDefaultValue {@link #DEFAULT_SPLIT_REMOTE}
96       */
97      public static final String CONFIG_PROP_SPLIT_REMOTE =
98              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitRemote";
99  
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 }