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 org.eclipse.aether.RepositorySystemSession;
22  import org.eclipse.aether.artifact.Artifact;
23  import org.eclipse.aether.metadata.Metadata;
24  import org.eclipse.aether.repository.RemoteRepository;
25  import org.eclipse.aether.repository.RepositoryKeyFunction;
26  import org.eclipse.aether.util.ConfigUtils;
27  
28  /**
29   * Support class for {@link LocalPathPrefixComposerFactory} implementations: it predefines and makes re-usable
30   * common configuration getters, and defines a support class for {@link LocalPathPrefixComposer} carrying same
31   * configuration and providing default implementation for all methods.
32   * <p>
33   * Implementors should extend this class to implement custom split strategies. If one needs to alter default
34   * configuration, they should override any configuration getter from this class.
35   *
36   * @see DefaultLocalPathPrefixComposerFactory
37   * @since 1.8.1
38   */
39  public abstract class LocalPathPrefixComposerFactorySupport implements LocalPathPrefixComposerFactory {
40  
41      /**
42       * Whether LRM should split local and remote artifacts.
43       *
44       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
45       * @configurationType {@link java.lang.Boolean}
46       * @configurationDefaultValue {@link #DEFAULT_SPLIT}
47       */
48      public static final String CONFIG_PROP_SPLIT = EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "split";
49  
50      public static final boolean DEFAULT_SPLIT = false;
51  
52      /**
53       * The prefix to use for locally installed artifacts.
54       *
55       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
56       * @configurationType {@link java.lang.String}
57       * @configurationDefaultValue {@link #DEFAULT_LOCAL_PREFIX}
58       */
59      public static final String CONFIG_PROP_LOCAL_PREFIX =
60              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "localPrefix";
61  
62      public static final String DEFAULT_LOCAL_PREFIX = "installed";
63  
64      /**
65       * Whether locally installed artifacts should be split by version (release/snapshot).
66       *
67       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
68       * @configurationType {@link java.lang.Boolean}
69       * @configurationDefaultValue {@link #DEFAULT_SPLIT_LOCAL}
70       */
71      public static final String CONFIG_PROP_SPLIT_LOCAL =
72              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitLocal";
73  
74      public static final boolean DEFAULT_SPLIT_LOCAL = false;
75  
76      /**
77       * The prefix to use for remotely cached artifacts.
78       *
79       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
80       * @configurationType {@link java.lang.String}
81       * @configurationDefaultValue {@link #DEFAULT_REMOTE_PREFIX}
82       */
83      public static final String CONFIG_PROP_REMOTE_PREFIX =
84              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "remotePrefix";
85  
86      public static final String DEFAULT_REMOTE_PREFIX = "cached";
87  
88      /**
89       * Whether cached artifacts should be split by version (release/snapshot).
90       *
91       * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
92       * @configurationType {@link java.lang.Boolean}
93       * @configurationDefaultValue {@link #DEFAULT_SPLIT_REMOTE}
94       */
95      public static final String CONFIG_PROP_SPLIT_REMOTE =
96              EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitRemote";
97  
98      public static final boolean DEFAULT_SPLIT_REMOTE = false;
99  
100     /**
101      * Whether cached artifacts should be split by origin repository (repository ID).
102      *
103      * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
104      * @configurationType {@link java.lang.Boolean}
105      * @configurationDefaultValue {@link #DEFAULT_SPLIT_REMOTE_REPOSITORY}
106      */
107     public static final String CONFIG_PROP_SPLIT_REMOTE_REPOSITORY =
108             EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitRemoteRepository";
109 
110     public static final boolean DEFAULT_SPLIT_REMOTE_REPOSITORY = false;
111 
112     /**
113      * For cached artifacts, if both splitRemote and splitRemoteRepository are set to true sets the splitting order:
114      * by default it is repositoryId/version (false) or version/repositoryId (true)
115      *
116      * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
117      * @configurationType {@link java.lang.Boolean}
118      * @configurationDefaultValue {@link #DEFAULT_SPLIT_REMOTE_REPOSITORY_LAST}
119      */
120     public static final String CONFIG_PROP_SPLIT_REMOTE_REPOSITORY_LAST =
121             EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "splitRemoteRepositoryLast";
122 
123     public static final boolean DEFAULT_SPLIT_REMOTE_REPOSITORY_LAST = false;
124 
125     /**
126      * The prefix to use for release artifacts.
127      *
128      * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
129      * @configurationType {@link java.lang.String}
130      * @configurationDefaultValue {@link #DEFAULT_RELEASES_PREFIX}
131      */
132     public static final String CONFIG_PROP_RELEASES_PREFIX =
133             EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "releasesPrefix";
134 
135     public static final String DEFAULT_RELEASES_PREFIX = "releases";
136 
137     /**
138      * The prefix to use for snapshot artifacts.
139      *
140      * @configurationSource {@link RepositorySystemSession#getConfigProperties()}
141      * @configurationType {@link java.lang.String}
142      * @configurationDefaultValue {@link #DEFAULT_SNAPSHOTS_PREFIX}
143      */
144     public static final String CONFIG_PROP_SNAPSHOTS_PREFIX =
145             EnhancedLocalRepositoryManagerFactory.CONFIG_PROPS_PREFIX + "snapshotsPrefix";
146 
147     public static final String DEFAULT_SNAPSHOTS_PREFIX = "snapshots";
148 
149     // Legacy support: properties were renamed in Resolver 2.0.x, but we should support 1.9.x properties as well
150     // These below are Resolver 1.9.x properties, are undocumented and shall be removed with Resolver 2.1.x (or later).
151 
152     private static final String R1_CONF_PROP_SPLIT = "aether.enhancedLocalRepository.split";
153 
154     private static final String R1_CONF_PROP_LOCAL_PREFIX = "aether.enhancedLocalRepository.localPrefix";
155 
156     private static final String R1_CONF_PROP_SPLIT_LOCAL = "aether.enhancedLocalRepository.splitLocal";
157 
158     private static final String R1_CONF_PROP_REMOTE_PREFIX = "aether.enhancedLocalRepository.remotePrefix";
159 
160     private static final String R1_CONF_PROP_SPLIT_REMOTE = "aether.enhancedLocalRepository.splitRemote";
161 
162     private static final String R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY =
163             "aether.enhancedLocalRepository.splitRemoteRepository";
164 
165     private static final String R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY_LAST =
166             "aether.enhancedLocalRepository.splitRemoteRepositoryLast";
167 
168     private static final String R1_CONF_PROP_RELEASES_PREFIX = "aether.enhancedLocalRepository.releasesPrefix";
169 
170     private static final String R1_CONF_PROP_SNAPSHOTS_PREFIX = "aether.enhancedLocalRepository.snapshotsPrefix";
171 
172     protected boolean isSplit(RepositorySystemSession session) {
173         return ConfigUtils.getBoolean(session, DEFAULT_SPLIT, CONFIG_PROP_SPLIT, R1_CONF_PROP_SPLIT);
174     }
175 
176     protected String getLocalPrefix(RepositorySystemSession session) {
177         return ConfigUtils.getString(
178                 session, DEFAULT_LOCAL_PREFIX, CONFIG_PROP_LOCAL_PREFIX, R1_CONF_PROP_LOCAL_PREFIX);
179     }
180 
181     protected boolean isSplitLocal(RepositorySystemSession session) {
182         return ConfigUtils.getBoolean(session, DEFAULT_SPLIT_LOCAL, CONFIG_PROP_SPLIT_LOCAL, R1_CONF_PROP_SPLIT_LOCAL);
183     }
184 
185     protected String getRemotePrefix(RepositorySystemSession session) {
186         return ConfigUtils.getString(
187                 session, DEFAULT_REMOTE_PREFIX, CONFIG_PROP_REMOTE_PREFIX, R1_CONF_PROP_REMOTE_PREFIX);
188     }
189 
190     protected boolean isSplitRemote(RepositorySystemSession session) {
191         return ConfigUtils.getBoolean(
192                 session, DEFAULT_SPLIT_REMOTE, CONFIG_PROP_SPLIT_REMOTE, R1_CONF_PROP_SPLIT_REMOTE);
193     }
194 
195     protected boolean isSplitRemoteRepository(RepositorySystemSession session) {
196         return ConfigUtils.getBoolean(
197                 session,
198                 DEFAULT_SPLIT_REMOTE_REPOSITORY,
199                 CONFIG_PROP_SPLIT_REMOTE_REPOSITORY,
200                 R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY);
201     }
202 
203     protected boolean isSplitRemoteRepositoryLast(RepositorySystemSession session) {
204         return ConfigUtils.getBoolean(
205                 session,
206                 DEFAULT_SPLIT_REMOTE_REPOSITORY_LAST,
207                 CONFIG_PROP_SPLIT_REMOTE_REPOSITORY_LAST,
208                 R1_CONF_PROP_SPLIT_REMOTE_REPOSITORY_LAST);
209     }
210 
211     protected String getReleasesPrefix(RepositorySystemSession session) {
212         return ConfigUtils.getString(
213                 session, DEFAULT_RELEASES_PREFIX, CONFIG_PROP_RELEASES_PREFIX, R1_CONF_PROP_RELEASES_PREFIX);
214     }
215 
216     protected String getSnapshotsPrefix(RepositorySystemSession session) {
217         return ConfigUtils.getString(
218                 session, DEFAULT_SNAPSHOTS_PREFIX, CONFIG_PROP_SNAPSHOTS_PREFIX, R1_CONF_PROP_SNAPSHOTS_PREFIX);
219     }
220 
221     /**
222      * Support class for composers: it defines protected members for all the predefined configuration values and
223      * provides default implementation for methods. Implementors may change it's behaviour by overriding methods.
224      */
225     @SuppressWarnings("checkstyle:parameternumber")
226     protected abstract static class LocalPathPrefixComposerSupport implements LocalPathPrefixComposer {
227         protected final boolean split;
228 
229         protected final String localPrefix;
230 
231         protected final boolean splitLocal;
232 
233         protected final String remotePrefix;
234 
235         protected final boolean splitRemote;
236 
237         protected final boolean splitRemoteRepository;
238 
239         protected final boolean splitRemoteRepositoryLast;
240 
241         protected final String releasesPrefix;
242 
243         protected final String snapshotsPrefix;
244 
245         protected final RepositoryKeyFunction repositoryKeyFunction;
246 
247         protected LocalPathPrefixComposerSupport(
248                 boolean split,
249                 String localPrefix,
250                 boolean splitLocal,
251                 String remotePrefix,
252                 boolean splitRemote,
253                 boolean splitRemoteRepository,
254                 boolean splitRemoteRepositoryLast,
255                 String releasesPrefix,
256                 String snapshotsPrefix,
257                 RepositoryKeyFunction repositoryKeyFunction) {
258             this.split = split;
259             this.localPrefix = localPrefix;
260             this.splitLocal = splitLocal;
261             this.remotePrefix = remotePrefix;
262             this.splitRemote = splitRemote;
263             this.splitRemoteRepository = splitRemoteRepository;
264             this.splitRemoteRepositoryLast = splitRemoteRepositoryLast;
265             this.releasesPrefix = releasesPrefix;
266             this.snapshotsPrefix = snapshotsPrefix;
267             this.repositoryKeyFunction = repositoryKeyFunction;
268         }
269 
270         @Override
271         public String getPathPrefixForLocalArtifact(Artifact artifact) {
272             if (!split) {
273                 return null;
274             }
275             String result = localPrefix;
276             if (splitLocal) {
277                 result += "/" + (artifact.isSnapshot() ? snapshotsPrefix : releasesPrefix);
278             }
279             return result;
280         }
281 
282         @Override
283         public String getPathPrefixForRemoteArtifact(Artifact artifact, RemoteRepository repository) {
284             if (!split) {
285                 return null;
286             }
287             String result = remotePrefix;
288             if (!splitRemoteRepositoryLast && splitRemoteRepository) {
289                 result += "/" + repositoryKeyFunction.apply(repository, null);
290             }
291             if (splitRemote) {
292                 result += "/" + (artifact.isSnapshot() ? snapshotsPrefix : releasesPrefix);
293             }
294             if (splitRemoteRepositoryLast && splitRemoteRepository) {
295                 result += "/" + repositoryKeyFunction.apply(repository, null);
296             }
297             return result;
298         }
299 
300         @Override
301         public String getPathPrefixForLocalMetadata(Metadata metadata) {
302             if (!split) {
303                 return null;
304             }
305             String result = localPrefix;
306             if (splitLocal) {
307                 result += "/" + (isSnapshot(metadata) ? snapshotsPrefix : releasesPrefix);
308             }
309             return result;
310         }
311 
312         @Override
313         public String getPathPrefixForRemoteMetadata(Metadata metadata, RemoteRepository repository) {
314             if (!split) {
315                 return null;
316             }
317             String result = remotePrefix;
318             if (!splitRemoteRepositoryLast && splitRemoteRepository) {
319                 result += "/" + repositoryKeyFunction.apply(repository, null);
320             }
321             if (splitRemote) {
322                 result += "/" + (isSnapshot(metadata) ? snapshotsPrefix : releasesPrefix);
323             }
324             if (splitRemoteRepositoryLast && splitRemoteRepository) {
325                 result += "/" + repositoryKeyFunction.apply(repository, null);
326             }
327             return result;
328         }
329 
330         protected boolean isSnapshot(Metadata metadata) {
331             return !metadata.getVersion().isEmpty() && metadata.getVersion().endsWith("-SNAPSHOT");
332         }
333     }
334 }