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