1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.eclipse.aether.internal.impl;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.net.URI;
26  import java.net.URISyntaxException;
27  import java.util.ArrayList;
28  import java.util.Collections;
29  import java.util.List;
30  
31  import org.eclipse.aether.ConfigurationProperties;
32  import org.eclipse.aether.RepositorySystemSession;
33  import org.eclipse.aether.artifact.Artifact;
34  import org.eclipse.aether.metadata.Metadata;
35  import org.eclipse.aether.repository.RemoteRepository;
36  import org.eclipse.aether.spi.artifact.ArtifactPredicate;
37  import org.eclipse.aether.spi.artifact.ArtifactPredicateFactory;
38  import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
39  import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactorySelector;
40  import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
41  import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
42  import org.eclipse.aether.transfer.NoRepositoryLayoutException;
43  import org.eclipse.aether.util.ConfigUtils;
44  
45  import static java.util.Objects.requireNonNull;
46  
47  
48  
49  
50  @Singleton
51  @Named(Maven2RepositoryLayoutFactory.NAME)
52  public final class Maven2RepositoryLayoutFactory implements RepositoryLayoutFactory {
53      public static final String NAME = "maven2";
54  
55      private static final String CONFIG_PROPS_PREFIX = ConfigurationProperties.PREFIX_LAYOUT + NAME + ".";
56  
57      
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68      public static final String CONFIG_PROP_CHECKSUMS_ALGORITHMS = CONFIG_PROPS_PREFIX + "checksumAlgorithms";
69  
70      public static final String DEFAULT_CHECKSUMS_ALGORITHMS = "SHA-1,MD5";
71  
72      private float priority;
73  
74      private final ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector;
75  
76      private final ArtifactPredicateFactory artifactPredicateFactory;
77  
78      public float getPriority() {
79          return priority;
80      }
81  
82      @Inject
83      public Maven2RepositoryLayoutFactory(
84              ChecksumAlgorithmFactorySelector checksumAlgorithmFactorySelector,
85              ArtifactPredicateFactory artifactPredicateFactory) {
86          this.checksumAlgorithmFactorySelector = requireNonNull(checksumAlgorithmFactorySelector);
87          this.artifactPredicateFactory = requireNonNull(artifactPredicateFactory);
88      }
89  
90      
91  
92  
93  
94  
95  
96      public Maven2RepositoryLayoutFactory setPriority(float priority) {
97          this.priority = priority;
98          return this;
99      }
100 
101     public RepositoryLayout newInstance(RepositorySystemSession session, RemoteRepository repository)
102             throws NoRepositoryLayoutException {
103         requireNonNull(session, "session cannot be null");
104         requireNonNull(repository, "repository cannot be null");
105         if (!"default".equals(repository.getContentType())) {
106             throw new NoRepositoryLayoutException(repository);
107         }
108 
109         List<ChecksumAlgorithmFactory> checksumsAlgorithms = checksumAlgorithmFactorySelector.selectList(
110                 ConfigUtils.parseCommaSeparatedUniqueNames(ConfigUtils.getString(
111                         session,
112                         DEFAULT_CHECKSUMS_ALGORITHMS,
113                         CONFIG_PROP_CHECKSUMS_ALGORITHMS + "." + repository.getId(),
114                         CONFIG_PROP_CHECKSUMS_ALGORITHMS)));
115 
116         return new Maven2RepositoryLayout(checksumsAlgorithms, artifactPredicateFactory.newInstance(session));
117     }
118 
119     private static class Maven2RepositoryLayout implements RepositoryLayout {
120         private final List<ChecksumAlgorithmFactory> configuredChecksumAlgorithms;
121         private final ArtifactPredicate artifactPredicate;
122 
123         private Maven2RepositoryLayout(
124                 List<ChecksumAlgorithmFactory> configuredChecksumAlgorithms, ArtifactPredicate artifactPredicate) {
125             this.configuredChecksumAlgorithms = Collections.unmodifiableList(configuredChecksumAlgorithms);
126             this.artifactPredicate = requireNonNull(artifactPredicate);
127         }
128 
129         private URI toUri(String path) {
130             try {
131                 return new URI(null, null, path, null);
132             } catch (URISyntaxException e) {
133                 throw new IllegalStateException(e);
134             }
135         }
136 
137         @Override
138         public List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories() {
139             return configuredChecksumAlgorithms;
140         }
141 
142         @Override
143         public boolean hasChecksums(Artifact artifact) {
144             return !artifactPredicate.isWithoutChecksum(artifact);
145         }
146 
147         @Override
148         public URI getLocation(Artifact artifact, boolean upload) {
149             StringBuilder path = new StringBuilder(128);
150 
151             path.append(artifact.getGroupId().replace('.', '/')).append('/');
152 
153             path.append(artifact.getArtifactId()).append('/');
154 
155             path.append(artifact.getBaseVersion()).append('/');
156 
157             path.append(artifact.getArtifactId()).append('-').append(artifact.getVersion());
158 
159             if (!artifact.getClassifier().isEmpty()) {
160                 path.append('-').append(artifact.getClassifier());
161             }
162 
163             if (!artifact.getExtension().isEmpty()) {
164                 path.append('.').append(artifact.getExtension());
165             }
166 
167             return toUri(path.toString());
168         }
169 
170         @Override
171         public URI getLocation(Metadata metadata, boolean upload) {
172             StringBuilder path = new StringBuilder(128);
173 
174             if (!metadata.getGroupId().isEmpty()) {
175                 path.append(metadata.getGroupId().replace('.', '/')).append('/');
176 
177                 if (!metadata.getArtifactId().isEmpty()) {
178                     path.append(metadata.getArtifactId()).append('/');
179 
180                     if (!metadata.getVersion().isEmpty()) {
181                         path.append(metadata.getVersion()).append('/');
182                     }
183                 }
184             }
185 
186             path.append(metadata.getType());
187 
188             return toUri(path.toString());
189         }
190 
191         @Override
192         public List<ChecksumLocation> getChecksumLocations(Artifact artifact, boolean upload, URI location) {
193             if (artifactPredicate.isWithoutChecksum(artifact) || artifactPredicate.isChecksum(artifact)) {
194                 return Collections.emptyList();
195             }
196             return getChecksumLocations(location);
197         }
198 
199         @Override
200         public List<ChecksumLocation> getChecksumLocations(Metadata metadata, boolean upload, URI location) {
201             return getChecksumLocations(location);
202         }
203 
204         private List<ChecksumLocation> getChecksumLocations(URI location) {
205             List<ChecksumLocation> checksumLocations = new ArrayList<>(configuredChecksumAlgorithms.size());
206             for (ChecksumAlgorithmFactory checksumAlgorithmFactory : configuredChecksumAlgorithms) {
207                 checksumLocations.add(ChecksumLocation.forLocation(location, checksumAlgorithmFactory));
208             }
209             return checksumLocations;
210         }
211     }
212 }