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.apache.maven.artifact.repository;
20  
21  import java.io.File;
22  import java.util.Collections;
23  import java.util.List;
24  import java.util.Objects;
25  
26  import org.apache.maven.RepositoryUtils;
27  import org.apache.maven.artifact.metadata.ArtifactMetadata;
28  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
29  import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
30  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataStoreException;
31  import org.apache.maven.repository.Proxy;
32  import org.eclipse.aether.DefaultRepositorySystemSession;
33  import org.eclipse.aether.RepositorySystem;
34  import org.eclipse.aether.RepositorySystemSession;
35  import org.eclipse.aether.artifact.Artifact;
36  import org.eclipse.aether.metadata.Metadata;
37  import org.eclipse.aether.repository.LocalArtifactRegistration;
38  import org.eclipse.aether.repository.LocalArtifactRequest;
39  import org.eclipse.aether.repository.LocalArtifactResult;
40  import org.eclipse.aether.repository.LocalMetadataRegistration;
41  import org.eclipse.aether.repository.LocalMetadataRequest;
42  import org.eclipse.aether.repository.LocalMetadataResult;
43  import org.eclipse.aether.repository.LocalRepository;
44  import org.eclipse.aether.repository.LocalRepositoryManager;
45  import org.eclipse.aether.repository.RemoteRepository;
46  
47  /**
48   * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
49   * of the public API. In particular, this class can be changed or deleted without prior notice.
50   *
51   * @author Benjamin Bentmann
52   */
53  public class LegacyLocalRepositoryManager implements LocalRepositoryManager {
54  
55      private final ArtifactRepository delegate;
56  
57      private final LocalRepository repo;
58  
59      private final boolean realLocalRepo;
60  
61      public static RepositorySystemSession overlay(
62              ArtifactRepository repository, RepositorySystemSession session, RepositorySystem system) {
63          return overlay(repository, session);
64      }
65  
66      public static RepositorySystemSession overlay(ArtifactRepository repository, RepositorySystemSession session) {
67          if (repository == null || repository.getBasedir() == null) {
68              return session;
69          }
70  
71          if (session != null) {
72              LocalRepositoryManager lrm = session.getLocalRepositoryManager();
73              if (lrm != null && lrm.getRepository().getBasedir().equals(new File(repository.getBasedir()))) {
74                  return session;
75              }
76          } else {
77              session = new DefaultRepositorySystemSession();
78          }
79  
80          final LocalRepositoryManager llrm = new LegacyLocalRepositoryManager(repository);
81  
82          return new DefaultRepositorySystemSession(session).setLocalRepositoryManager(llrm);
83      }
84  
85      private LegacyLocalRepositoryManager(ArtifactRepository delegate) {
86          this.delegate = Objects.requireNonNull(delegate, "delegate cannot be null");
87  
88          ArtifactRepositoryLayout layout = delegate.getLayout();
89          repo = new LocalRepository(
90                  new File(delegate.getBasedir()),
91                  (layout != null) ? layout.getClass().getSimpleName() : "legacy");
92  
93          /*
94           * NOTE: "invoker:install" vs "appassembler:assemble": Both mojos use the artifact installer to put an artifact
95           * into a repository. In the first case, the result needs to be a proper local repository that one can use for
96           * local artifact resolution. In the second case, the result needs to precisely obey the path information of the
97           * repository's layout to allow pointing at artifacts within the repository. Unfortunately,
98           * DefaultRepositoryLayout does not correctly describe the layout of a local repository which unlike a remote
99           * repository never uses timestamps in the filename of a snapshot artifact. The discrepancy gets notable when a
100          * remotely resolved snapshot artifact gets passed into pathOf(). So producing a proper local artifact path
101          * using DefaultRepositoryLayout requires us to enforce usage of the artifact's base version. This
102          * transformation however contradicts the other use case of precisely obeying the repository's layout. The below
103          * flag tries to detect which use case applies to make both plugins happy.
104          */
105         realLocalRepo = (layout instanceof DefaultRepositoryLayout) && "local".equals(delegate.getId());
106     }
107 
108     public LocalRepository getRepository() {
109         return repo;
110     }
111 
112     public String getPathForLocalArtifact(Artifact artifact) {
113         if (realLocalRepo) {
114             return delegate.pathOf(RepositoryUtils.toArtifact(artifact.setVersion(artifact.getBaseVersion())));
115         }
116         return delegate.pathOf(RepositoryUtils.toArtifact(artifact));
117     }
118 
119     public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) {
120         return delegate.pathOf(RepositoryUtils.toArtifact(artifact));
121     }
122 
123     public String getPathForLocalMetadata(Metadata metadata) {
124         return delegate.pathOfLocalRepositoryMetadata(new ArtifactMetadataAdapter(metadata), delegate);
125     }
126 
127     public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) {
128         return delegate.pathOfLocalRepositoryMetadata(
129                 new ArtifactMetadataAdapter(metadata), new ArtifactRepositoryAdapter(repository));
130     }
131 
132     public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) {
133         String path = getPathForLocalArtifact(request.getArtifact());
134         File file = new File(getRepository().getBasedir(), path);
135 
136         LocalArtifactResult result = new LocalArtifactResult(request);
137         if (file.isFile()) {
138             result.setFile(file);
139             result.setAvailable(true);
140         }
141 
142         return result;
143     }
144 
145     public LocalMetadataResult find(RepositorySystemSession session, LocalMetadataRequest request) {
146         Metadata metadata = request.getMetadata();
147 
148         String path;
149         if (request.getRepository() == null) {
150             path = getPathForLocalMetadata(metadata);
151         } else {
152             path = getPathForRemoteMetadata(metadata, request.getRepository(), request.getContext());
153         }
154 
155         File file = new File(getRepository().getBasedir(), path);
156 
157         LocalMetadataResult result = new LocalMetadataResult(request);
158         if (file.isFile()) {
159             result.setFile(file);
160         }
161 
162         return result;
163     }
164 
165     public void add(RepositorySystemSession session, LocalArtifactRegistration request) {
166         // noop
167     }
168 
169     public void add(RepositorySystemSession session, LocalMetadataRegistration request) {
170         // noop
171     }
172 
173     static class ArtifactMetadataAdapter implements ArtifactMetadata {
174 
175         private final Metadata metadata;
176 
177         ArtifactMetadataAdapter(Metadata metadata) {
178             this.metadata = metadata;
179         }
180 
181         public boolean storedInArtifactVersionDirectory() {
182             return metadata.getVersion().length() > 0;
183         }
184 
185         public boolean storedInGroupDirectory() {
186             return metadata.getArtifactId().length() <= 0;
187         }
188 
189         public String getGroupId() {
190             return nullify(metadata.getGroupId());
191         }
192 
193         public String getArtifactId() {
194             return nullify(metadata.getArtifactId());
195         }
196 
197         public String getBaseVersion() {
198             return nullify(metadata.getVersion());
199         }
200 
201         private String nullify(String str) {
202             return (str == null || str.length() <= 0) ? null : str;
203         }
204 
205         public Object getKey() {
206             return metadata.toString();
207         }
208 
209         public String getRemoteFilename() {
210             return metadata.getType();
211         }
212 
213         public String getLocalFilename(ArtifactRepository repository) {
214             return insertRepositoryKey(getRemoteFilename(), repository.getKey());
215         }
216 
217         private String insertRepositoryKey(String filename, String repositoryKey) {
218             String result;
219             int idx = filename.indexOf('.');
220             if (idx < 0) {
221                 result = filename + '-' + repositoryKey;
222             } else {
223                 result = filename.substring(0, idx) + '-' + repositoryKey + filename.substring(idx);
224             }
225             return result;
226         }
227 
228         public void merge(org.apache.maven.repository.legacy.metadata.ArtifactMetadata metadata) {
229             // not used
230         }
231 
232         public void merge(ArtifactMetadata metadata) {
233             // not used
234         }
235 
236         public void storeInLocalRepository(ArtifactRepository localRepository, ArtifactRepository remoteRepository)
237                 throws RepositoryMetadataStoreException {
238             // not used
239         }
240 
241         public String extendedToString() {
242             return metadata.toString();
243         }
244     }
245 
246     static class ArtifactRepositoryAdapter implements ArtifactRepository {
247 
248         private final RemoteRepository repository;
249 
250         ArtifactRepositoryAdapter(RemoteRepository repository) {
251             this.repository = repository;
252         }
253 
254         public String pathOf(org.apache.maven.artifact.Artifact artifact) {
255             return null;
256         }
257 
258         public String pathOfRemoteRepositoryMetadata(ArtifactMetadata artifactMetadata) {
259             return null;
260         }
261 
262         public String pathOfLocalRepositoryMetadata(ArtifactMetadata metadata, ArtifactRepository repository) {
263             return null;
264         }
265 
266         public String getUrl() {
267             return repository.getUrl();
268         }
269 
270         public void setUrl(String url) {}
271 
272         public String getBasedir() {
273             return null;
274         }
275 
276         public String getProtocol() {
277             return repository.getProtocol();
278         }
279 
280         public String getId() {
281             return repository.getId();
282         }
283 
284         public void setId(String id) {}
285 
286         public ArtifactRepositoryPolicy getSnapshots() {
287             return null;
288         }
289 
290         public void setSnapshotUpdatePolicy(ArtifactRepositoryPolicy policy) {}
291 
292         public ArtifactRepositoryPolicy getReleases() {
293             return null;
294         }
295 
296         public void setReleaseUpdatePolicy(ArtifactRepositoryPolicy policy) {}
297 
298         public ArtifactRepositoryLayout getLayout() {
299             return null;
300         }
301 
302         public void setLayout(ArtifactRepositoryLayout layout) {}
303 
304         public String getKey() {
305             return getId();
306         }
307 
308         public boolean isUniqueVersion() {
309             return true;
310         }
311 
312         public boolean isBlacklisted() {
313             return false;
314         }
315 
316         public void setBlacklisted(boolean blackListed) {}
317 
318         public org.apache.maven.artifact.Artifact find(org.apache.maven.artifact.Artifact artifact) {
319             return null;
320         }
321 
322         public List<String> findVersions(org.apache.maven.artifact.Artifact artifact) {
323             return Collections.emptyList();
324         }
325 
326         public boolean isProjectAware() {
327             return false;
328         }
329 
330         public void setAuthentication(Authentication authentication) {}
331 
332         public Authentication getAuthentication() {
333             return null;
334         }
335 
336         public void setProxy(Proxy proxy) {}
337 
338         public Proxy getProxy() {
339             return null;
340         }
341 
342         public List<ArtifactRepository> getMirroredRepositories() {
343             return Collections.emptyList();
344         }
345 
346         public void setMirroredRepositories(List<ArtifactRepository> mirroredRepositories) {}
347 
348         public boolean isBlocked() {
349             return false;
350         }
351 
352         public void setBlocked(boolean blocked) {}
353     }
354 }