1 package org.eclipse.aether.internal.impl;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Map;
28
29 import static java.util.Objects.requireNonNull;
30
31 import java.util.Objects;
32 import java.util.Properties;
33
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.RemoteRepository;
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 class EnhancedLocalRepositoryManager
62 extends SimpleLocalRepositoryManager
63 {
64
65 private static final String LOCAL_REPO_ID = "";
66
67 private final String trackingFilename;
68
69 private final TrackingFileManager trackingFileManager;
70
71 private final LocalPathPrefixComposer localPathPrefixComposer;
72
73 EnhancedLocalRepositoryManager( File basedir,
74 LocalPathComposer localPathComposer,
75 String trackingFilename,
76 TrackingFileManager trackingFileManager,
77 LocalPathPrefixComposer localPathPrefixComposer )
78 {
79 super( basedir, "enhanced", localPathComposer );
80 this.trackingFilename = requireNonNull( trackingFilename );
81 this.trackingFileManager = requireNonNull( trackingFileManager );
82 this.localPathPrefixComposer = requireNonNull( localPathPrefixComposer );
83 }
84
85 private String concatPaths( String prefix, String artifactPath )
86 {
87 if ( prefix == null || prefix.isEmpty() )
88 {
89 return artifactPath;
90 }
91 return prefix + '/' + artifactPath;
92 }
93
94 @Override
95 public String getPathForLocalArtifact( Artifact artifact )
96 {
97 return concatPaths(
98 localPathPrefixComposer.getPathPrefixForLocalArtifact( artifact ),
99 super.getPathForLocalArtifact( artifact )
100 );
101 }
102
103 @Override
104 public String getPathForRemoteArtifact( Artifact artifact, RemoteRepository repository, String context )
105 {
106 return concatPaths(
107 localPathPrefixComposer.getPathPrefixForRemoteArtifact( artifact, repository ),
108 super.getPathForRemoteArtifact( artifact, repository, context )
109 );
110 }
111
112 @Override
113 public String getPathForLocalMetadata( Metadata metadata )
114 {
115 return concatPaths(
116 localPathPrefixComposer.getPathPrefixForLocalMetadata( metadata ),
117 super.getPathForLocalMetadata( metadata )
118 );
119 }
120
121 @Override
122 public String getPathForRemoteMetadata( Metadata metadata, RemoteRepository repository, String context )
123 {
124 return concatPaths(
125 localPathPrefixComposer.getPathPrefixForRemoteMetadata( metadata, repository ),
126 super.getPathForRemoteMetadata( metadata, repository, context )
127 );
128 }
129
130 @Override
131 public LocalArtifactResult find( RepositorySystemSession session, LocalArtifactRequest request )
132 {
133 Artifact artifact = request.getArtifact();
134 LocalArtifactResult result = new LocalArtifactResult( request );
135
136 String path;
137 File file;
138
139
140 if ( Objects.equals( artifact.getVersion(), artifact.getBaseVersion() ) )
141 {
142 path = getPathForLocalArtifact( artifact );
143 file = new File( getRepository().getBasedir(), path );
144 checkFind( file, result );
145 }
146
147 if ( !result.isAvailable() )
148 {
149 for ( RemoteRepository repository : request.getRepositories() )
150 {
151 path = getPathForRemoteArtifact( artifact, repository, request.getContext() );
152 file = new File( getRepository().getBasedir(), path );
153
154 checkFind( file, result );
155
156 if ( result.isAvailable() )
157 {
158 break;
159 }
160 }
161 }
162
163 return result;
164 }
165
166 private void checkFind( File file, LocalArtifactResult result )
167 {
168 if ( file.isFile() )
169 {
170 result.setFile( file );
171
172 Properties props = readRepos( file );
173
174 if ( props.get( getKey( file, LOCAL_REPO_ID ) ) != null )
175 {
176
177 result.setAvailable( true );
178 }
179 else
180 {
181 String context = result.getRequest().getContext();
182 for ( RemoteRepository repository : result.getRequest().getRepositories() )
183 {
184 if ( props.get( getKey( file, getRepositoryKey( repository, context ) ) ) != null )
185 {
186
187
188 result.setAvailable( true );
189 result.setRepository( repository );
190 break;
191 }
192 }
193 if ( !result.isAvailable() && !isTracked( props, file ) )
194 {
195
196
197
198
199 result.setAvailable( true );
200 }
201 }
202 }
203 }
204
205 @Override
206 public void add( RepositorySystemSession session, LocalArtifactRegistration request )
207 {
208 Collection<String> repositories;
209 if ( request.getRepository() == null )
210 {
211 repositories = Collections.singleton( LOCAL_REPO_ID );
212 }
213 else
214 {
215 repositories = getRepositoryKeys( request.getRepository(), request.getContexts() );
216 }
217 if ( request.getRepository() == null )
218 {
219 addArtifact( request.getArtifact(), repositories, null, null );
220 }
221 else
222 {
223 for ( String context : request.getContexts() )
224 {
225 addArtifact( request.getArtifact(), repositories, request.getRepository(), context );
226 }
227 }
228 }
229
230 private Collection<String> getRepositoryKeys( RemoteRepository repository, Collection<String> contexts )
231 {
232 Collection<String> keys = new HashSet<>();
233
234 if ( contexts != null )
235 {
236 for ( String context : contexts )
237 {
238 keys.add( getRepositoryKey( repository, context ) );
239 }
240 }
241
242 return keys;
243 }
244
245 private void addArtifact( Artifact artifact, Collection<String> repositories, RemoteRepository repository,
246 String context )
247 {
248 requireNonNull( artifact, "artifact cannot be null" );
249 String path = repository == null ? getPathForLocalArtifact( artifact )
250 : getPathForRemoteArtifact( artifact, repository, context );
251 File file = new File( getRepository().getBasedir(), path );
252 addRepo( file, repositories );
253 }
254
255 private Properties readRepos( File artifactFile )
256 {
257 File trackingFile = getTrackingFile( artifactFile );
258
259 Properties props = trackingFileManager.read( trackingFile );
260
261 return ( props != null ) ? props : new Properties();
262 }
263
264 private void addRepo( File artifactFile, Collection<String> repositories )
265 {
266 Map<String, String> updates = new HashMap<>();
267 for ( String repository : repositories )
268 {
269 updates.put( getKey( artifactFile, repository ), "" );
270 }
271
272 File trackingFile = getTrackingFile( artifactFile );
273
274 trackingFileManager.update( trackingFile, updates );
275 }
276
277 private File getTrackingFile( File artifactFile )
278 {
279 return new File( artifactFile.getParentFile(), trackingFilename );
280 }
281
282 private String getKey( File file, String repository )
283 {
284 return file.getName() + '>' + repository;
285 }
286
287 private boolean isTracked( Properties props, File file )
288 {
289 if ( props != null )
290 {
291 String keyPrefix = file.getName() + '>';
292 for ( Object key : props.keySet() )
293 {
294 if ( key.toString().startsWith( keyPrefix ) )
295 {
296 return true;
297 }
298 }
299 }
300 return false;
301 }
302
303 }