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