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.nio.file.Files;
22  import java.nio.file.Path;
23  import java.util.Objects;
24  import java.util.SortedSet;
25  import java.util.TreeSet;
26  
27  import org.eclipse.aether.RepositorySystemSession;
28  import org.eclipse.aether.artifact.Artifact;
29  import org.eclipse.aether.metadata.Metadata;
30  import org.eclipse.aether.repository.LocalArtifactRegistration;
31  import org.eclipse.aether.repository.LocalArtifactRequest;
32  import org.eclipse.aether.repository.LocalArtifactResult;
33  import org.eclipse.aether.repository.LocalMetadataRegistration;
34  import org.eclipse.aether.repository.LocalMetadataRequest;
35  import org.eclipse.aether.repository.LocalMetadataResult;
36  import org.eclipse.aether.repository.LocalRepository;
37  import org.eclipse.aether.repository.LocalRepositoryManager;
38  import org.eclipse.aether.repository.RemoteRepository;
39  import org.eclipse.aether.util.StringDigestUtil;
40  
41  import static java.util.Objects.requireNonNull;
42  
43  /**
44   * A local repository manager that realizes the classical Maven 2.0 local repository.
45   */
46  class SimpleLocalRepositoryManager implements LocalRepositoryManager {
47  
48      private final LocalRepository repository;
49  
50      private final LocalPathComposer localPathComposer;
51  
52      SimpleLocalRepositoryManager(Path basePath, String type, LocalPathComposer localPathComposer) {
53          requireNonNull(basePath, "base directory cannot be null");
54          repository = new LocalRepository(basePath.toAbsolutePath(), type);
55          this.localPathComposer = requireNonNull(localPathComposer);
56      }
57  
58      @Override
59      public LocalRepository getRepository() {
60          return repository;
61      }
62  
63      @Override
64      public String getPathForLocalArtifact(Artifact artifact) {
65          requireNonNull(artifact, "artifact cannot be null");
66          return localPathComposer.getPathForArtifact(artifact, true);
67      }
68  
69      @Override
70      public String getPathForRemoteArtifact(Artifact artifact, RemoteRepository repository, String context) {
71          requireNonNull(artifact, "artifact cannot be null");
72          requireNonNull(repository, "repository cannot be null");
73          return localPathComposer.getPathForArtifact(artifact, false);
74      }
75  
76      @Override
77      public String getPathForLocalMetadata(Metadata metadata) {
78          requireNonNull(metadata, "metadata cannot be null");
79          return localPathComposer.getPathForMetadata(metadata, "local");
80      }
81  
82      @Override
83      public String getPathForRemoteMetadata(Metadata metadata, RemoteRepository repository, String context) {
84          requireNonNull(metadata, "metadata cannot be null");
85          requireNonNull(repository, "repository cannot be null");
86          return localPathComposer.getPathForMetadata(metadata, getRepositoryKey(repository, context));
87      }
88  
89      /**
90       * Returns {@link RemoteRepository#getId()}, unless {@link RemoteRepository#isRepositoryManager()} returns
91       * {@code true}, in which case this method creates unique identifier based on ID and current configuration
92       * of the remote repository (as it may change).
93       */
94      protected String getRepositoryKey(RemoteRepository repository, String context) {
95          String key;
96  
97          if (repository.isRepositoryManager()) {
98              // repository serves dynamic contents, take request parameters into account for key
99  
100             StringBuilder buffer = new StringBuilder(128);
101 
102             buffer.append(repository.getId());
103 
104             buffer.append('-');
105 
106             SortedSet<String> subKeys = new TreeSet<>();
107             for (RemoteRepository mirroredRepo : repository.getMirroredRepositories()) {
108                 subKeys.add(mirroredRepo.getId());
109             }
110 
111             StringDigestUtil sha1 = StringDigestUtil.sha1();
112             sha1.update(context);
113             for (String subKey : subKeys) {
114                 sha1.update(subKey);
115             }
116             buffer.append(sha1.digest());
117 
118             key = buffer.toString();
119         } else {
120             // repository serves static contents, its id is sufficient as key
121 
122             key = repository.getId();
123         }
124 
125         return key;
126     }
127 
128     @Override
129     public LocalArtifactResult find(RepositorySystemSession session, LocalArtifactRequest request) {
130         requireNonNull(session, "session cannot be null");
131         requireNonNull(request, "request cannot be null");
132         Artifact artifact = request.getArtifact();
133         LocalArtifactResult result = new LocalArtifactResult(request);
134 
135         String path;
136         Path filePath;
137 
138         // Local repository CANNOT have timestamped installed, they are created only during deploy
139         if (Objects.equals(artifact.getVersion(), artifact.getBaseVersion())) {
140             path = getPathForLocalArtifact(artifact);
141             filePath = getRepository().getBasePath().resolve(path);
142             if (Files.isRegularFile(filePath)) {
143                 result.setPath(filePath);
144                 result.setAvailable(true);
145             }
146         }
147 
148         if (!result.isAvailable()) {
149             for (RemoteRepository repository : request.getRepositories()) {
150                 path = getPathForRemoteArtifact(artifact, repository, request.getContext());
151                 filePath = getRepository().getBasePath().resolve(path);
152                 if (Files.isRegularFile(filePath)) {
153                     result.setPath(filePath);
154                     result.setAvailable(true);
155                     break;
156                 }
157             }
158         }
159 
160         return result;
161     }
162 
163     @Override
164     public void add(RepositorySystemSession session, LocalArtifactRegistration request) {
165         requireNonNull(session, "session cannot be null");
166         requireNonNull(request, "request cannot be null");
167         // noop
168     }
169 
170     @Override
171     public LocalMetadataResult find(RepositorySystemSession session, LocalMetadataRequest request) {
172         requireNonNull(session, "session cannot be null");
173         requireNonNull(request, "request cannot be null");
174         LocalMetadataResult result = new LocalMetadataResult(request);
175 
176         String path;
177 
178         Metadata metadata = request.getMetadata();
179         String context = request.getContext();
180         RemoteRepository remote = request.getRepository();
181 
182         if (remote != null) {
183             path = getPathForRemoteMetadata(metadata, remote, context);
184         } else {
185             path = getPathForLocalMetadata(metadata);
186         }
187 
188         Path filePath = getRepository().getBasePath().resolve(path);
189         if (Files.isRegularFile(filePath)) {
190             result.setPath(filePath);
191         }
192 
193         return result;
194     }
195 
196     @Override
197     public void add(RepositorySystemSession session, LocalMetadataRegistration request) {
198         requireNonNull(session, "session cannot be null");
199         requireNonNull(request, "request cannot be null");
200         // noop
201     }
202 
203     @Override
204     public String toString() {
205         return String.valueOf(getRepository());
206     }
207 }