This project has retired. For details please refer to its
Attic page.
FileMetadataRepository xref
1 package org.apache.archiva.metadata.repository.file;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.checksum.ChecksumAlgorithm;
23 import org.apache.archiva.configuration.ArchivaConfiguration;
24 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
25 import org.apache.archiva.metadata.QueryParameter;
26 import org.apache.archiva.metadata.model.ArtifactMetadata;
27 import org.apache.archiva.metadata.model.CiManagement;
28 import org.apache.archiva.metadata.model.Dependency;
29 import org.apache.archiva.metadata.model.IssueManagement;
30 import org.apache.archiva.metadata.model.License;
31 import org.apache.archiva.metadata.model.MailingList;
32 import org.apache.archiva.metadata.model.MetadataFacet;
33 import org.apache.archiva.metadata.model.MetadataFacetFactory;
34 import org.apache.archiva.metadata.model.Organization;
35 import org.apache.archiva.metadata.model.ProjectMetadata;
36 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
37 import org.apache.archiva.metadata.model.ProjectVersionReference;
38 import org.apache.archiva.metadata.model.Scm;
39 import org.apache.archiva.metadata.repository.AbstractMetadataRepository;
40 import org.apache.archiva.metadata.repository.MetadataRepository;
41 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
42 import org.apache.archiva.metadata.repository.MetadataResolutionException;
43 import org.apache.archiva.metadata.repository.MetadataService;
44 import org.apache.archiva.metadata.repository.RepositorySession;
45 import org.apache.commons.lang3.StringUtils;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48
49 import javax.annotation.ParametersAreNonnullByDefault;
50 import java.io.FileNotFoundException;
51 import java.io.IOException;
52 import java.io.InputStream;
53 import java.io.OutputStream;
54 import java.nio.file.FileVisitOption;
55 import java.nio.file.Files;
56 import java.nio.file.NoSuchFileException;
57 import java.nio.file.Path;
58 import java.nio.file.Paths;
59 import java.time.Instant;
60 import java.time.ZoneId;
61 import java.time.ZonedDateTime;
62 import java.util.ArrayList;
63 import java.util.Arrays;
64 import java.util.Collection;
65 import java.util.Collections;
66 import java.util.Comparator;
67 import java.util.HashMap;
68 import java.util.HashSet;
69 import java.util.LinkedHashSet;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.Objects;
73 import java.util.Properties;
74 import java.util.Set;
75 import java.util.StringTokenizer;
76 import java.util.stream.Collectors;
77 import java.util.stream.Stream;
78
79
80
81
82
83
84
85 @ParametersAreNonnullByDefault
86 public class FileMetadataRepository
87 extends AbstractMetadataRepository implements MetadataRepository {
88
89 private final ArchivaConfiguration configuration;
90
91 private Logger log = LoggerFactory.getLogger(FileMetadataRepository.class);
92
93 private static final String PROJECT_METADATA_KEY = "project-metadata";
94
95 private static final String PROJECT_VERSION_METADATA_KEY = "version-metadata";
96
97 private static final String NAMESPACE_METADATA_KEY = "namespace-metadata";
98
99 private static final String METADATA_KEY = "metadata";
100
101 private Map<String, Path> baseDirectory = new HashMap<>();
102
103 public FileMetadataRepository(MetadataService metadataService,
104 ArchivaConfiguration configuration) {
105 super(metadataService);
106 this.configuration = configuration;
107 }
108
109 private Path getBaseDirectory(String repoId)
110 throws IOException {
111 if (!baseDirectory.containsKey(repoId)) {
112 Path baseDir;
113 ManagedRepositoryConfiguration managedRepositoryConfiguration =
114 configuration.getConfiguration().getManagedRepositoriesAsMap().get(repoId);
115 if (managedRepositoryConfiguration == null) {
116 baseDir = Files.createTempDirectory(repoId);
117 } else {
118 baseDir = Paths.get(managedRepositoryConfiguration.getLocation());
119 }
120 baseDirectory.put(repoId, baseDir.resolve(".archiva"));
121 }
122 return baseDirectory.get(repoId);
123 }
124
125 private Path getDirectory(String repoId)
126 throws IOException {
127 return getBaseDirectory(repoId).resolve("content");
128 }
129
130 @Override
131 public void updateProject(RepositorySession session, String repoId, ProjectMetadata project) {
132 updateProject(session, repoId, project.getNamespace(), project.getId());
133 }
134
135 private void updateProject(RepositorySession session, String repoId, String namespace, String id) {
136
137 updateNamespace(session, repoId, namespace);
138
139 try {
140 Path namespaceDirectory = getDirectory(repoId).resolve(namespace);
141 Properties properties = new Properties();
142 properties.setProperty("namespace", namespace);
143 properties.setProperty("id", id);
144 writeProperties(properties, namespaceDirectory.resolve(id), PROJECT_METADATA_KEY);
145 } catch (IOException e) {
146 log.error("Could not update project {}, {}, {}: {}", repoId, namespace, id, e.getMessage(), e);
147 }
148 }
149
150 @Override
151 public void updateProjectVersion(RepositorySession session, String repoId, String namespace, String projectId,
152 ProjectVersionMetadata versionMetadata) {
153
154 try {
155 updateProject(session, repoId, namespace, projectId);
156
157 Path directory =
158 getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + versionMetadata.getId());
159
160 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
161
162 for (Object key : new ArrayList<>(properties.keySet())) {
163 String name = (String) key;
164 if (!name.contains(":") && !name.equals("facetIds")) {
165 properties.remove(name);
166 }
167
168
169 clearMetadataFacetProperties(versionMetadata.getFacetList(), properties, "");
170 }
171 properties.setProperty("id", versionMetadata.getId());
172 setProperty(properties, "name", versionMetadata.getName());
173 setProperty(properties, "description", versionMetadata.getDescription());
174 setProperty(properties, "url", versionMetadata.getUrl());
175 setProperty(properties, "incomplete", String.valueOf(versionMetadata.isIncomplete()));
176 if (versionMetadata.getScm() != null) {
177 setProperty(properties, "scm.connection", versionMetadata.getScm().getConnection());
178 setProperty(properties, "scm.developerConnection", versionMetadata.getScm().getDeveloperConnection());
179 setProperty(properties, "scm.url", versionMetadata.getScm().getUrl());
180 }
181 if (versionMetadata.getCiManagement() != null) {
182 setProperty(properties, "ci.system", versionMetadata.getCiManagement().getSystem());
183 setProperty(properties, "ci.url", versionMetadata.getCiManagement().getUrl());
184 }
185 if (versionMetadata.getIssueManagement() != null) {
186 setProperty(properties, "issue.system", versionMetadata.getIssueManagement().getSystem());
187 setProperty(properties, "issue.url", versionMetadata.getIssueManagement().getUrl());
188 }
189 if (versionMetadata.getOrganization() != null) {
190 setProperty(properties, "org.name", versionMetadata.getOrganization().getName());
191 setProperty(properties, "org.url", versionMetadata.getOrganization().getUrl());
192 }
193 int i = 0;
194 for (License license : versionMetadata.getLicenses()) {
195 setProperty(properties, "license." + i + ".name", license.getName());
196 setProperty(properties, "license." + i + ".url", license.getUrl());
197 i++;
198 }
199 i = 0;
200 for (MailingList mailingList : versionMetadata.getMailingLists()) {
201 setProperty(properties, "mailingList." + i + ".archive", mailingList.getMainArchiveUrl());
202 setProperty(properties, "mailingList." + i + ".name", mailingList.getName());
203 setProperty(properties, "mailingList." + i + ".post", mailingList.getPostAddress());
204 setProperty(properties, "mailingList." + i + ".unsubscribe", mailingList.getUnsubscribeAddress());
205 setProperty(properties, "mailingList." + i + ".subscribe", mailingList.getSubscribeAddress());
206 setProperty(properties, "mailingList." + i + ".otherArchives",
207 join(mailingList.getOtherArchives()));
208 i++;
209 }
210 i = 0;
211 ProjectVersionReferenceersionReference.html#ProjectVersionReference">ProjectVersionReference reference = new ProjectVersionReference();
212 reference.setNamespace(namespace);
213 reference.setProjectId(projectId);
214 reference.setProjectVersion(versionMetadata.getId());
215 reference.setReferenceType(ProjectVersionReference.ReferenceType.DEPENDENCY);
216 for (Dependency dependency : versionMetadata.getDependencies()) {
217 setProperty(properties, "dependency." + i + ".classifier", dependency.getClassifier());
218 setProperty(properties, "dependency." + i + ".scope", dependency.getScope());
219 setProperty(properties, "dependency." + i + ".systemPath", dependency.getSystemPath());
220 setProperty(properties, "dependency." + i + ".artifactId", dependency.getArtifactId());
221 setProperty(properties, "dependency." + i + ".groupId", dependency.getNamespace());
222 setProperty(properties, "dependency." + i + ".version", dependency.getVersion());
223 setProperty(properties, "dependency." + i + ".type", dependency.getType());
224 setProperty(properties, "dependency." + i + ".optional", String.valueOf(dependency.isOptional()));
225
226 updateProjectReference(repoId, dependency.getNamespace(), dependency.getArtifactId(),
227 dependency.getVersion(), reference);
228
229 i++;
230 }
231 Set<String> facetIds = new LinkedHashSet<>(versionMetadata.getFacetIds());
232 facetIds.addAll(Arrays.asList(properties.getProperty("facetIds", "").split(",")));
233 properties.setProperty("facetIds", join(facetIds));
234
235 updateProjectVersionFacets(versionMetadata, properties);
236
237 writeProperties(properties, directory, PROJECT_VERSION_METADATA_KEY);
238 } catch (IOException e) {
239 log.error("Could not update project version {}, {}, {}: {}", repoId, namespace, versionMetadata.getId(), e.getMessage(), e);
240 }
241 }
242
243 private void updateProjectVersionFacets(ProjectVersionMetadata versionMetadata, Properties properties) {
244 for (MetadataFacet facet : versionMetadata.getFacetList()) {
245 for (Map.Entry<String, String> entry : facet.toProperties().entrySet()) {
246 properties.setProperty(facet.getFacetId() + ":" + entry.getKey(), entry.getValue());
247 }
248 }
249 }
250
251 private static void clearMetadataFacetProperties(Collection<MetadataFacet> facetList, Properties properties,
252 String prefix) {
253 List<Object> propsToRemove = new ArrayList<>();
254 for (MetadataFacet facet : facetList) {
255 for (Object key : new ArrayList<>(properties.keySet())) {
256 String keyString = (String) key;
257 if (keyString.startsWith(prefix + facet.getFacetId() + ":")) {
258 propsToRemove.add(key);
259 }
260 }
261 }
262
263 for (Object key : propsToRemove) {
264 properties.remove(key);
265 }
266 }
267
268 private void updateProjectReference(String repoId, String namespace, String projectId, String projectVersion,
269 ProjectVersionReference reference) {
270 try {
271 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + projectVersion);
272
273 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
274 int i = Integer.parseInt(properties.getProperty("ref:lastReferenceNum", "-1")) + 1;
275 setProperty(properties, "ref:lastReferenceNum", Integer.toString(i));
276 setProperty(properties, "ref:reference." + i + ".namespace", reference.getNamespace());
277 setProperty(properties, "ref:reference." + i + ".projectId", reference.getProjectId());
278 setProperty(properties, "ref:reference." + i + ".projectVersion", reference.getProjectVersion());
279 setProperty(properties, "ref:reference." + i + ".referenceType", reference.getReferenceType().toString());
280
281 writeProperties(properties, directory, PROJECT_VERSION_METADATA_KEY);
282 } catch (IOException e) {
283 log.error("Could not update project reference {}, {}, {}, {}: {}", repoId, namespace, projectId, projectVersion, e.getMessage(), e);
284 }
285 }
286
287 @Override
288 public void updateNamespace(RepositorySession session, String repoId, String namespace) {
289 try {
290 Path namespaceDirectory = getDirectory(repoId).resolve(namespace);
291 Properties properties = new Properties();
292 properties.setProperty("namespace", namespace);
293 writeProperties(properties, namespaceDirectory, NAMESPACE_METADATA_KEY);
294
295 } catch (IOException e) {
296 log.error("Could not update namespace of {}, {}: {}", repoId, namespace, e.getMessage(), e);
297 }
298 }
299
300 @Override
301 public List<String> getMetadataFacets(RepositorySession session, String repoId, String facetId)
302 throws MetadataRepositoryException {
303 try {
304 Path directory = getMetadataDirectory(repoId, facetId);
305 if (!(Files.exists(directory) && Files.isDirectory(directory))) {
306 return Collections.emptyList();
307 }
308 List<String> facets;
309 final String searchFile = METADATA_KEY + ".properties";
310 try (Stream<Path> fs = Files.walk(directory, FileVisitOption.FOLLOW_LINKS)) {
311 facets = fs.filter(Files::isDirectory).filter(path -> Files.exists(path.resolve(searchFile)))
312 .map(path -> directory.relativize(path).toString()).collect(Collectors.toList());
313 }
314 return facets;
315 } catch (IOException e) {
316 throw new MetadataRepositoryException(e.getMessage(), e);
317 }
318 }
319
320 @Override
321 public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException {
322 final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory(facetClazz);
323 if (metadataFacetFactory == null) {
324 return null;
325 }
326 final String facetId = metadataFacetFactory.getFacetId();
327 final String searchFile = METADATA_KEY + ".properties";
328 try {
329 Path directory = getMetadataDirectory(repositoryId, facetId);
330 return Files.walk(directory, FileVisitOption.FOLLOW_LINKS).filter(Files::isDirectory)
331 .filter(path -> Files.exists(path.resolve(searchFile)))
332 .map(path -> directory.relativize(path).toString())
333 .sorted()
334 .skip(queryParameter.getOffset())
335 .limit(queryParameter.getLimit())
336 .map(name -> getMetadataFacet(session, repositoryId, facetClazz, name));
337 } catch (IOException e) {
338 throw new MetadataRepositoryException(e.getMessage(), e);
339 }
340 }
341
342 @Override
343 public boolean hasMetadataFacet(RepositorySession session, String repositoryId, String facetId)
344 throws MetadataRepositoryException {
345
346 try {
347 Path directory = getMetadataDirectory(repositoryId, facetId);
348 if (!(Files.exists(directory) && Files.isDirectory(directory))) {
349 return false;
350 }
351 final String searchFile = METADATA_KEY + ".properties";
352 try (Stream<Path> fs = Files.walk(directory, FileVisitOption.FOLLOW_LINKS)) {
353 return fs.filter(Files::isDirectory).anyMatch(path -> Files.exists(path.resolve(searchFile)));
354 }
355 } catch (IOException e) {
356 log.error("Could not retrieve facet metatadata {}, {}: {}", repositoryId, facetId, e.getMessage(), e);
357 throw new MetadataRepositoryException(e.getMessage(), e);
358 }
359
360 }
361
362
363 @Override
364 public <T extends MetadataFacet> T getMetadataFacet(RepositorySession session, String repositoryId, Class<T> facetClazz, String name) {
365 final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory(facetClazz);
366 if (metadataFacetFactory == null) {
367 return null;
368 }
369 final String facetId = metadataFacetFactory.getFacetId();
370
371 Properties properties;
372 try {
373 properties =
374 readProperties(getMetadataDirectory(repositoryId, facetId).resolve(name), METADATA_KEY);
375 } catch (NoSuchFileException | FileNotFoundException e) {
376 return null;
377 } catch (IOException e) {
378 log.error("Could not read properties from {}, {}: {}", repositoryId, facetId, e.getMessage(), e);
379 return null;
380 }
381 T metadataFacet = null;
382 if (metadataFacetFactory != null) {
383 metadataFacet = metadataFacetFactory.createMetadataFacet(repositoryId, name);
384 Map<String, String> map = new HashMap<>();
385 for (Object key : new ArrayList<>(properties.keySet())) {
386 String property = (String) key;
387 map.put(property, properties.getProperty(property));
388 }
389 metadataFacet.fromProperties(map);
390 }
391 return metadataFacet;
392 }
393
394
395 @Override
396 public void addMetadataFacet(RepositorySession session, String repositoryId, MetadataFacet metadataFacet) {
397 Properties properties = new Properties();
398 properties.putAll(metadataFacet.toProperties());
399
400 try {
401 Path directory =
402 getMetadataDirectory(repositoryId, metadataFacet.getFacetId()).resolve(metadataFacet.getName());
403 writeProperties(properties, directory, METADATA_KEY);
404 } catch (IOException e) {
405
406 log.error(e.getMessage(), e);
407 }
408 }
409
410 @Override
411 public void removeMetadataFacets(RepositorySession session, String repositoryId, String facetId)
412 throws MetadataRepositoryException {
413 try {
414 Path dir = getMetadataDirectory(repositoryId, facetId);
415 org.apache.archiva.common.utils.FileUtils.deleteDirectory(dir);
416 } catch (IOException e) {
417 throw new MetadataRepositoryException(e.getMessage(), e);
418 }
419 }
420
421 @Override
422 public void removeMetadataFacet(RepositorySession session, String repoId, String facetId, String name)
423 throws MetadataRepositoryException {
424 try {
425 Path dir = getMetadataDirectory(repoId, facetId).resolve(name);
426 org.apache.archiva.common.utils.FileUtils.deleteDirectory(dir);
427 } catch (IOException e) {
428 throw new MetadataRepositoryException(e.getMessage(), e);
429 }
430 }
431
432 @Override
433 public List<ArtifactMetadata> getArtifactsByDateRange(RepositorySession session, String repoId, ZonedDateTime startTime, ZonedDateTime endTime)
434 throws MetadataRepositoryException {
435 try {
436 List<ArtifactMetadata> artifacts = new ArrayList<>();
437 for (String ns : getRootNamespaces(session, repoId)) {
438 getArtifactsByDateRange(session, artifacts, repoId, ns, startTime, endTime);
439 }
440 artifacts.sort(new ArtifactComparator());
441 return artifacts;
442 } catch (MetadataResolutionException e) {
443 throw new MetadataRepositoryException(e.getMessage(), e);
444 }
445 }
446
447
448
449
450
451
452
453
454
455
456
457
458
459 @Override
460 public Stream<ArtifactMetadata> getArtifactByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException {
461 try {
462 List<ArtifactMetadata> artifacts = new ArrayList<>();
463 for (String ns : getRootNamespaces(session, repositoryId)) {
464 getArtifactsByDateRange(session, artifacts, repositoryId, ns, startTime, endTime);
465 }
466 Comparator<ArtifactMetadata> comp = getArtifactMetadataComparator(queryParameter, "whenGathered");
467 return artifacts.stream().sorted(comp).skip(queryParameter.getOffset()).limit(queryParameter.getLimit());
468
469 } catch (MetadataResolutionException e) {
470 throw new MetadataRepositoryException(e.getMessage(), e);
471 }
472 }
473
474
475 private void getArtifactsByDateRange(RepositorySession session, List<ArtifactMetadata> artifacts, String repoId, String ns, ZonedDateTime startTime,
476 ZonedDateTime endTime)
477 throws MetadataRepositoryException {
478 try {
479 for (String namespace : this.getChildNamespaces(session, repoId, ns)) {
480 getArtifactsByDateRange(session, artifacts, repoId, ns + "." + namespace, startTime, endTime);
481 }
482
483 for (String project : getProjects(session, repoId, ns)) {
484 for (String version : getProjectVersions(session, repoId, ns, project)) {
485 for (ArtifactMetadata artifact : getArtifacts(session, repoId, ns, project, version)) {
486 if (startTime == null || startTime.isBefore(ZonedDateTime.from(artifact.getWhenGathered().toInstant().atZone(ZoneId.systemDefault())))) {
487 if (endTime == null || endTime.isAfter(ZonedDateTime.from(artifact.getWhenGathered().toInstant().atZone(ZoneId.systemDefault())))) {
488 artifacts.add(artifact);
489 }
490 }
491 }
492 }
493 }
494 } catch (MetadataResolutionException e) {
495 throw new MetadataRepositoryException(e.getMessage(), e);
496 }
497 }
498
499
500 @Override
501 public List<ArtifactMetadata> getArtifacts( RepositorySession session, String repoId, String namespace, String projectId,
502 String projectVersion)
503 throws MetadataResolutionException {
504 try {
505 Map<String, ArtifactMetadata> artifacts = new HashMap<>();
506
507 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + projectVersion);
508
509 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
510
511 for (Map.Entry entry : properties.entrySet()) {
512 String name = (String) entry.getKey();
513 StringTokenizer tok = new StringTokenizer(name, ":");
514 if (tok.hasMoreTokens() && "artifact".equals(tok.nextToken())) {
515 String field = tok.nextToken();
516 String id = tok.nextToken();
517
518 ArtifactMetadata artifact = artifacts.get(id);
519 if (artifact == null) {
520 artifact = new ArtifactMetadata();
521 artifact.setRepositoryId(repoId);
522 artifact.setNamespace(namespace);
523 artifact.setProject(projectId);
524 artifact.setProjectVersion(projectVersion);
525 artifact.setVersion(projectVersion);
526 artifact.setId(id);
527 artifacts.put(id, artifact);
528 }
529
530 String value = (String) entry.getValue();
531 if ("updated".equals(field)) {
532 artifact.setFileLastModified(Long.parseLong(value));
533 } else if ("size".equals(field)) {
534 artifact.setSize(Long.valueOf(value));
535 } else if ("whenGathered".equals(field)) {
536 artifact.setWhenGathered(ZonedDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(value)), ZoneId.of("GMT")));
537 } else if ("version".equals(field)) {
538 artifact.setVersion(value);
539 } else if (field.startsWith("checksum")) {
540 String algorithmStr = StringUtils.removeStart( name, "artifact:checksum:"+id+":");
541 artifact.setChecksum( ChecksumAlgorithm.valueOf( algorithmStr ), value );
542 } else if ("facetIds".equals(field)) {
543 if (value.length() > 0) {
544 String propertyPrefix = "artifact:facet:" + id + ":";
545 for (String facetId : value.split(",")) {
546 MetadataFacetFactory factory = getFacetFactory(facetId);
547 if (factory == null) {
548 log.error("Attempted to load unknown artifact metadata facet: {}", facetId);
549 } else {
550 MetadataFacet facet = factory.createMetadataFacet();
551 String prefix = propertyPrefix + facet.getFacetId();
552 Map<String, String> map = new HashMap<>();
553 for (Object key : new ArrayList<>(properties.keySet())) {
554 String property = (String) key;
555 if (property.startsWith(prefix)) {
556 map.put(property.substring(prefix.length() + 1),
557 properties.getProperty(property));
558 }
559 }
560 facet.fromProperties(map);
561 artifact.addFacet(facet);
562 }
563 }
564 }
565
566 updateArtifactFacets(artifact, properties);
567 }
568 }
569 }
570 return new ArrayList<>(artifacts.values());
571 } catch (IOException e) {
572 throw new MetadataResolutionException(e.getMessage(), e);
573 }
574 }
575
576
577 @Override
578 public void close() {
579
580 }
581
582
583 private void updateArtifactFacets(ArtifactMetadata artifact, Properties properties) {
584 String propertyPrefix = "artifact:facet:" + artifact.getId() + ":";
585 for (MetadataFacet facet : artifact.getFacetList()) {
586 for (Map.Entry<String, String> e : facet.toProperties().entrySet()) {
587 String key = propertyPrefix + facet.getFacetId() + ":" + e.getKey();
588 properties.setProperty(key, e.getValue());
589 }
590 }
591 }
592
593 @Override
594 public List<ArtifactMetadata> getArtifactsByChecksum(RepositorySession session, String repositoryId, String checksum)
595 throws MetadataRepositoryException {
596 try {
597
598
599
600
601
602 return getArtifactStream( session, repositoryId ).filter(
603 a -> a.hasChecksum( checksum )
604 ).collect( Collectors.toList() );
605 } catch (MetadataResolutionException e) {
606 throw new MetadataRepositoryException(e.getMessage(), e);
607 }
608 }
609
610 @Override
611 public void removeNamespace(RepositorySession session, String repositoryId, String project)
612 throws MetadataRepositoryException {
613 try {
614 Path namespaceDirectory = getDirectory(repositoryId).resolve(project);
615 org.apache.archiva.common.utils.FileUtils.deleteDirectory(namespaceDirectory);
616
617
618
619
620 } catch (IOException e) {
621 throw new MetadataRepositoryException(e.getMessage(), e);
622 }
623 }
624
625 @Override
626 public void removeTimestampedArtifact( RepositorySession session, ArtifactMetadata artifactMetadata, String baseVersion)
627 throws MetadataRepositoryException {
628
629 try {
630 Path directory = getDirectory(artifactMetadata.getRepositoryId()).resolve(
631 artifactMetadata.getNamespace() + "/" + artifactMetadata.getProject() + "/"
632 + baseVersion);
633
634 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
635
636 String id = artifactMetadata.getId();
637
638 properties.remove("artifact:updated:" + id);
639 properties.remove("artifact:whenGathered:" + id);
640 properties.remove("artifact:size:" + id);
641 artifactMetadata.getChecksums().entrySet().stream().forEach( entry ->
642 properties.remove( "artifact:checksum:"+id+":"+entry.getKey().name() ));
643 properties.remove("artifact:version:" + id);
644 properties.remove("artifact:facetIds:" + id);
645
646 String prefix = "artifact:facet:" + id + ":";
647 for (Object key : new ArrayList<>(properties.keySet())) {
648 String property = (String) key;
649 if (property.startsWith(prefix)) {
650 properties.remove(property);
651 }
652 }
653
654 writeProperties(properties, directory, PROJECT_VERSION_METADATA_KEY);
655 } catch (IOException e) {
656 throw new MetadataRepositoryException(e.getMessage(), e);
657 }
658
659 }
660
661 @Override
662 public void removeArtifact(RepositorySession session, String repoId, String namespace, String project, String version, String id)
663 throws MetadataRepositoryException {
664 try {
665 Path directory = getDirectory(repoId).resolve(namespace + "/" + project + "/" + version);
666
667 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
668
669 properties.remove("artifact:updated:" + id);
670 properties.remove("artifact:whenGathered:" + id);
671 properties.remove("artifact:size:" + id);
672 properties.remove("artifact:version:" + id);
673 properties.remove("artifact:facetIds:" + id);
674
675 String facetPrefix = "artifact:facet:" + id + ":";
676 String checksumPrefix = "artifact:checksum:"+id+":";
677 for (String property : properties.stringPropertyNames()) {
678 if (property.startsWith( checksumPrefix )) {
679 properties.remove( property );
680 } else if (property.startsWith(facetPrefix)) {
681 properties.remove(property);
682 }
683 }
684
685 org.apache.archiva.common.utils.FileUtils.deleteDirectory(directory);
686
687 } catch (IOException e) {
688 throw new MetadataRepositoryException(e.getMessage(), e);
689 }
690 }
691
692
693
694
695
696
697
698
699
700
701
702
703 @Override
704 public void removeFacetFromArtifact( RepositorySession session, String repositoryId, String namespace, String project, String projectVersion,
705 MetadataFacet metadataFacet)
706 throws MetadataRepositoryException {
707 throw new UnsupportedOperationException("not implemented");
708 }
709
710 @Override
711 public void removeRepository(RepositorySession session, String repoId)
712 throws MetadataRepositoryException {
713 try {
714 Path dir = getDirectory(repoId);
715 org.apache.archiva.common.utils.FileUtils.deleteDirectory(dir);
716 } catch (IOException e) {
717 throw new MetadataRepositoryException(e.getMessage(), e);
718 }
719 }
720
721
722 @Override
723 public List<ArtifactMetadata> getArtifactsByProjectVersionFacet( RepositorySession session, String key, String value, String repositoryId)
724 throws MetadataRepositoryException {
725 throw new UnsupportedOperationException("not yet implemented in File backend");
726 }
727
728 @Override
729 public List<ArtifactMetadata> getArtifactsByAttribute( RepositorySession session, String key, String value, String repositoryId)
730 throws MetadataRepositoryException {
731 throw new UnsupportedOperationException("not yet implemented in File backend");
732 }
733
734 @Override
735 public List<ArtifactMetadata> getArtifactsByProjectVersionAttribute( RepositorySession session, String key, String value, String repositoryId)
736 throws MetadataRepositoryException {
737 throw new UnsupportedOperationException("getArtifactsByProjectVersionAttribute not yet implemented in File backend");
738 }
739
740 private Path getMetadataDirectory(String repoId, String facetId)
741 throws IOException {
742 return getBaseDirectory(repoId).resolve("facets/" + facetId);
743 }
744
745 private String join(Collection<String> ids) {
746 if (ids != null && !ids.isEmpty()) {
747 StringBuilder s = new StringBuilder();
748 for (String id : ids) {
749 s.append(id);
750 s.append(",");
751 }
752 return s.substring(0, s.length() - 1);
753 }
754 return "";
755 }
756
757 private void setProperty(Properties properties, String name, String value) {
758 if (value != null) {
759 properties.setProperty(name, value);
760 }
761 }
762
763 @Override
764 public void updateArtifact(RepositorySession session, String repoId, String namespace, String projectId, String projectVersion,
765 ArtifactMetadata artifact) {
766 try {
767 ProjectVersionMetadatatVersionMetadata.html#ProjectVersionMetadata">ProjectVersionMetadata metadata = new ProjectVersionMetadata();
768 metadata.setId(projectVersion);
769 updateProjectVersion(session, repoId, namespace, projectId, metadata);
770
771 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + projectVersion);
772
773 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
774
775 clearMetadataFacetProperties(artifact.getFacetList(), properties,
776 "artifact:facet:" + artifact.getId() + ":");
777
778 String id = artifact.getId();
779 properties.setProperty("artifact:updated:" + id,
780 Long.toString(artifact.getFileLastModified().toInstant().toEpochMilli()));
781 properties.setProperty("artifact:whenGathered:" + id,
782 Long.toString(artifact.getWhenGathered().toInstant().toEpochMilli()));
783 properties.setProperty("artifact:size:" + id, Long.toString(artifact.getSize()));
784 artifact.getChecksums().entrySet().stream().forEach( entry ->
785 properties.setProperty( "artifact:checksum:"+id+":"+entry.getKey().name(), entry.getValue() ));
786 properties.setProperty("artifact:version:" + id, artifact.getVersion());
787
788 Set<String> facetIds = new LinkedHashSet<>(artifact.getFacetIds());
789 String property = "artifact:facetIds:" + id;
790 facetIds.addAll(Arrays.asList(properties.getProperty(property, "").split(",")));
791 properties.setProperty(property, join(facetIds));
792
793 updateArtifactFacets(artifact, properties);
794
795 writeProperties(properties, directory, PROJECT_VERSION_METADATA_KEY);
796 } catch (IOException e) {
797
798 log.error(e.getMessage(), e);
799 }
800 }
801
802 private Properties readOrCreateProperties(Path directory, String propertiesKey) {
803 try {
804 return readProperties(directory, propertiesKey);
805 } catch (FileNotFoundException | NoSuchFileException e) {
806
807 } catch (IOException e) {
808
809 log.error(e.getMessage(), e);
810 }
811 return new Properties();
812 }
813
814 private Properties readProperties(Path directory, String propertiesKey)
815 throws IOException {
816 Properties properties = new Properties();
817 try (InputStream in = Files.newInputStream(directory.resolve(propertiesKey + ".properties"))) {
818
819 properties.load(in);
820 }
821 return properties;
822 }
823
824 @Override
825 public ProjectMetadata getProject(RepositorySession session, String repoId, String namespace, String projectId)
826 throws MetadataResolutionException {
827 try {
828 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId);
829
830 Properties properties = readOrCreateProperties(directory, PROJECT_METADATA_KEY);
831
832 ProjectMetadata project = null;
833
834 String id = properties.getProperty("id");
835 if (id != null) {
836 project = new ProjectMetadata();
837 project.setNamespace(properties.getProperty("namespace"));
838 project.setId(id);
839 }
840
841 return project;
842 } catch (IOException e) {
843 throw new MetadataResolutionException(e.getMessage(), e);
844 }
845 }
846
847 @Override
848 public ProjectVersionMetadata getProjectVersion(RepositorySession session, String repoId, String namespace, String projectId,
849 String projectVersion)
850 throws MetadataResolutionException {
851 try {
852 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + projectVersion);
853
854 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
855 String id = properties.getProperty("id");
856 ProjectVersionMetadata versionMetadata = null;
857 if (id != null) {
858 versionMetadata = new ProjectVersionMetadata();
859 versionMetadata.setId(id);
860 versionMetadata.setName(properties.getProperty("name"));
861 versionMetadata.setDescription(properties.getProperty("description"));
862 versionMetadata.setUrl(properties.getProperty("url"));
863 versionMetadata.setIncomplete(Boolean.valueOf(properties.getProperty("incomplete", "false")));
864
865 String scmConnection = properties.getProperty("scm.connection");
866 String scmDeveloperConnection = properties.getProperty("scm.developerConnection");
867 String scmUrl = properties.getProperty("scm.url");
868 if (scmConnection != null || scmDeveloperConnection != null || scmUrl != null) {
869 Scmva/metadata/model/Scm.html#Scm">Scm scm = new Scm();
870 scm.setConnection(scmConnection);
871 scm.setDeveloperConnection(scmDeveloperConnection);
872 scm.setUrl(scmUrl);
873 versionMetadata.setScm(scm);
874 }
875
876 String ciSystem = properties.getProperty("ci.system");
877 String ciUrl = properties.getProperty("ci.url");
878 if (ciSystem != null || ciUrl != null) {
879 CiManagementata/model/CiManagement.html#CiManagement">CiManagement ci = new CiManagement();
880 ci.setSystem(ciSystem);
881 ci.setUrl(ciUrl);
882 versionMetadata.setCiManagement(ci);
883 }
884
885 String issueSystem = properties.getProperty("issue.system");
886 String issueUrl = properties.getProperty("issue.url");
887 if (issueSystem != null || issueUrl != null) {
888 IssueManagementanagement.html#IssueManagement">IssueManagement issueManagement = new IssueManagement();
889 issueManagement.setSystem(issueSystem);
890 issueManagement.setUrl(issueUrl);
891 versionMetadata.setIssueManagement(issueManagement);
892 }
893
894 String orgName = properties.getProperty("org.name");
895 String orgUrl = properties.getProperty("org.url");
896 if (orgName != null || orgUrl != null) {
897 Organizationta/model/Organization.html#Organization">Organization org = new Organization();
898 org.setName(orgName);
899 org.setUrl(orgUrl);
900 versionMetadata.setOrganization(org);
901 }
902
903 boolean done = false;
904 int i = 0;
905 while (!done) {
906 String licenseName = properties.getProperty("license." + i + ".name");
907 String licenseUrl = properties.getProperty("license." + i + ".url");
908 if (licenseName != null || licenseUrl != null) {
909 Licenseata/model/License.html#License">License license = new License();
910 license.setName(licenseName);
911 license.setUrl(licenseUrl);
912 versionMetadata.addLicense(license);
913 } else {
914 done = true;
915 }
916 i++;
917 }
918
919 done = false;
920 i = 0;
921 while (!done) {
922 String mailingListName = properties.getProperty("mailingList." + i + ".name");
923 if (mailingListName != null) {
924 MailingListl/MailingList.html#MailingList">MailingList mailingList = new MailingList();
925 mailingList.setName(mailingListName);
926 mailingList.setMainArchiveUrl(properties.getProperty("mailingList." + i + ".archive"));
927 String p = properties.getProperty("mailingList." + i + ".otherArchives");
928 if (p != null && p.length() > 0) {
929 mailingList.setOtherArchives(Arrays.asList(p.split(",")));
930 } else {
931 mailingList.setOtherArchives(Collections.emptyList());
932 }
933 mailingList.setPostAddress(properties.getProperty("mailingList." + i + ".post"));
934 mailingList.setSubscribeAddress(properties.getProperty("mailingList." + i + ".subscribe"));
935 mailingList.setUnsubscribeAddress(
936 properties.getProperty("mailingList." + i + ".unsubscribe"));
937 versionMetadata.addMailingList(mailingList);
938 } else {
939 done = true;
940 }
941 i++;
942 }
943
944 done = false;
945 i = 0;
946 while (!done) {
947 String dependencyArtifactId = properties.getProperty("dependency." + i + ".artifactId");
948 if (dependencyArtifactId != null) {
949 Dependencydel/Dependency.html#Dependency">Dependency dependency = new Dependency();
950 dependency.setArtifactId(dependencyArtifactId);
951 dependency.setNamespace(properties.getProperty("dependency." + i + ".groupId"));
952 dependency.setClassifier(properties.getProperty("dependency." + i + ".classifier"));
953 dependency.setOptional(
954 Boolean.valueOf(properties.getProperty("dependency." + i + ".optional")));
955 dependency.setScope(properties.getProperty("dependency." + i + ".scope"));
956 dependency.setSystemPath(properties.getProperty("dependency." + i + ".systemPath"));
957 dependency.setType(properties.getProperty("dependency." + i + ".type"));
958 dependency.setVersion(properties.getProperty("dependency." + i + ".version"));
959 dependency.setOptional(
960 Boolean.valueOf(properties.getProperty("dependency." + i + ".optional")));
961 versionMetadata.addDependency(dependency);
962 } else {
963 done = true;
964 }
965 i++;
966 }
967
968 String facetIds = properties.getProperty("facetIds", "");
969 if (facetIds.length() > 0) {
970 for (String facetId : facetIds.split(",")) {
971 MetadataFacetFactory factory = getFacetFactory(facetId);
972 if (factory == null) {
973 log.error("Attempted to load unknown project version metadata facet: {}", facetId);
974 } else {
975 MetadataFacet facet = factory.createMetadataFacet();
976 Map<String, String> map = new HashMap<>();
977 for (Object key : new ArrayList<>(properties.keySet())) {
978 String property = (String) key;
979 if (property.startsWith(facet.getFacetId())) {
980 map.put(property.substring(facet.getFacetId().length() + 1),
981 properties.getProperty(property));
982 }
983 }
984 facet.fromProperties(map);
985 versionMetadata.addFacet(facet);
986 }
987 }
988 }
989
990 updateProjectVersionFacets(versionMetadata, properties);
991 }
992 return versionMetadata;
993 } catch (IOException e) {
994 throw new MetadataResolutionException(e.getMessage(), e);
995 }
996 }
997
998 @Override
999 public List<String> getArtifactVersions( RepositorySession session, String repoId, String namespace, String projectId,
1000 String projectVersion)
1001 throws MetadataResolutionException {
1002 try {
1003 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + projectVersion);
1004
1005 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
1006
1007 Set<String> versions = new HashSet<>();
1008 for (Map.Entry entry : properties.entrySet()) {
1009 String name = (String) entry.getKey();
1010 if (name.startsWith("artifact:version:")) {
1011 versions.add((String) entry.getValue());
1012 }
1013 }
1014 return new ArrayList<>( versions );
1015 } catch (IOException e) {
1016 throw new MetadataResolutionException(e.getMessage(), e);
1017 }
1018 }
1019
1020 @Override
1021 public List<ProjectVersionReference> getProjectReferences( RepositorySession session, String repoId, String namespace, String projectId,
1022 String projectVersion)
1023 throws MetadataResolutionException {
1024 try {
1025 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + projectVersion);
1026
1027 Properties properties = readOrCreateProperties(directory, PROJECT_VERSION_METADATA_KEY);
1028 int numberOfRefs = Integer.parseInt(properties.getProperty("ref:lastReferenceNum", "-1")) + 1;
1029
1030 List<ProjectVersionReference> references = new ArrayList<>();
1031 for (int i = 0; i < numberOfRefs; i++) {
1032 ProjectVersionReferenceersionReference.html#ProjectVersionReference">ProjectVersionReference reference = new ProjectVersionReference();
1033 reference.setProjectId(properties.getProperty("ref:reference." + i + ".projectId"));
1034 reference.setNamespace(properties.getProperty("ref:reference." + i + ".namespace"));
1035 reference.setProjectVersion(properties.getProperty("ref:reference." + i + ".projectVersion"));
1036 reference.setReferenceType(ProjectVersionReference.ReferenceType.valueOf(
1037 properties.getProperty("ref:reference." + i + ".referenceType")));
1038 references.add(reference);
1039 }
1040 return references;
1041 } catch (IOException e) {
1042 throw new MetadataResolutionException(e.getMessage(), e);
1043 }
1044 }
1045
1046 @Override
1047 public List<String> getRootNamespaces( RepositorySession session, String repoId)
1048 throws MetadataResolutionException {
1049 return this.getChildNamespaces(session, repoId, null);
1050 }
1051
1052 private Stream<String> getAllNamespacesStream(RepositorySession session, String repoId) {
1053 Path directory = null;
1054 try
1055 {
1056 directory = getDirectory(repoId);
1057 }
1058 catch ( IOException e )
1059 {
1060 return Stream.empty( );
1061 }
1062 if (!(Files.exists(directory) && Files.isDirectory(directory))) {
1063 return Stream.empty( );
1064 }
1065 final String searchFile = NAMESPACE_METADATA_KEY + ".properties";
1066 try
1067 {
1068 return Files.list(directory).filter(Files::isDirectory).filter(path ->
1069 Files.exists(path.resolve(searchFile))
1070 ).map(path -> path.getFileName().toString());
1071 }
1072 catch ( IOException e )
1073 {
1074 return Stream.empty( );
1075 }
1076 }
1077
1078 @Override
1079 public List<String> getChildNamespaces( RepositorySession session, String repoId, String baseNamespace)
1080 throws MetadataResolutionException {
1081 try {
1082 List<String> allNamespaces;
1083 Path directory = getDirectory(repoId);
1084 if (!(Files.exists(directory) && Files.isDirectory(directory))) {
1085 return Collections.emptyList();
1086 }
1087 final String searchFile = NAMESPACE_METADATA_KEY + ".properties";
1088 try (Stream<Path> fs = Files.list(directory)) {
1089 allNamespaces = fs.filter(Files::isDirectory).filter(path ->
1090 Files.exists(path.resolve(searchFile))
1091 ).map(path -> path.getFileName().toString()).collect(Collectors.toList());
1092 }
1093
1094 Set<String> namespaces = new LinkedHashSet<>();
1095 int fromIndex = baseNamespace != null ? baseNamespace.length() + 1 : 0;
1096 for (String namespace : allNamespaces) {
1097 if (baseNamespace == null || namespace.startsWith(baseNamespace + ".")) {
1098 int i = namespace.indexOf('.', fromIndex);
1099 if (i >= 0) {
1100 namespaces.add(namespace.substring(fromIndex, i));
1101 } else {
1102 namespaces.add(namespace.substring(fromIndex));
1103 }
1104 }
1105 }
1106 return new ArrayList<>(namespaces);
1107 } catch (IOException e) {
1108 throw new MetadataResolutionException(e.getMessage(), e);
1109 }
1110 }
1111
1112 @Override
1113 public List<String> getProjects( RepositorySession session, String repoId, String namespace)
1114 throws MetadataResolutionException {
1115 try {
1116 List<String> projects;
1117 Path directory = getDirectory(repoId).resolve(namespace);
1118 if (!(Files.exists(directory) && Files.isDirectory(directory))) {
1119 return Collections.emptyList();
1120 }
1121 final String searchFile = PROJECT_METADATA_KEY + ".properties";
1122 try (Stream<Path> fs = Files.list(directory)) {
1123 projects = fs.filter(Files::isDirectory).filter(path ->
1124 Files.exists(path.resolve(searchFile))
1125 ).map(path -> path.getFileName().toString()).collect(Collectors.toList());
1126 }
1127
1128 return projects;
1129 } catch (IOException e) {
1130 throw new MetadataResolutionException(e.getMessage(), e);
1131 }
1132 }
1133
1134 @Override
1135 public List<String> getProjectVersions( RepositorySession session, String repoId, String namespace, String projectId)
1136 throws MetadataResolutionException {
1137 try {
1138 List<String> projectVersions;
1139 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId);
1140 if (!(Files.exists(directory) && Files.isDirectory(directory))) {
1141 return Collections.emptyList();
1142 }
1143 final String searchFile = PROJECT_VERSION_METADATA_KEY + ".properties";
1144 try (Stream<Path> fs = Files.list(directory)) {
1145 projectVersions = fs.filter(Files::isDirectory).filter(path ->
1146 Files.exists(path.resolve(searchFile))
1147 ).map(path -> path.getFileName().toString()).collect(Collectors.toList());
1148 }
1149 return projectVersions;
1150 } catch (IOException e) {
1151 throw new MetadataResolutionException(e.getMessage(), e);
1152 }
1153 }
1154
1155 @Override
1156 public void removeProject(RepositorySession session, String repositoryId, String namespace, String projectId)
1157 throws MetadataRepositoryException {
1158 try {
1159 Path directory = getDirectory(repositoryId).resolve(namespace + "/" + projectId);
1160 org.apache.archiva.common.utils.FileUtils.deleteDirectory(directory);
1161 } catch (IOException e) {
1162 throw new MetadataRepositoryException(e.getMessage(), e);
1163 }
1164 }
1165
1166 @Override
1167 public void removeProjectVersion(RepositorySession session, String repoId, String namespace, String projectId, String projectVersion)
1168 throws MetadataRepositoryException {
1169 try {
1170 Path directory = getDirectory(repoId).resolve(namespace + "/" + projectId + "/" + projectVersion);
1171 org.apache.archiva.common.utils.FileUtils.deleteDirectory(directory);
1172 } catch (IOException e) {
1173 throw new MetadataRepositoryException(e.getMessage(), e);
1174 }
1175
1176 }
1177
1178 private void writeProperties(Properties properties, Path directory, String propertiesKey)
1179 throws IOException {
1180 Files.createDirectories(directory);
1181 try (OutputStream os = Files.newOutputStream(directory.resolve(propertiesKey + ".properties"))) {
1182 properties.store(os, null);
1183 }
1184 }
1185
1186 private static class ArtifactComparator
1187 implements Comparator<ArtifactMetadata> {
1188 @Override
1189 public int compare(ArtifactMetadata/../../org/apache/archiva/metadata/model/ArtifactMetadata.html#ArtifactMetadata">ArtifactMetadata artifact1, ArtifactMetadata artifact2) {
1190 if (artifact1.getWhenGathered() == artifact2.getWhenGathered()) {
1191 return 0;
1192 }
1193 if (artifact1.getWhenGathered() == null) {
1194 return 1;
1195 }
1196 if (artifact2.getWhenGathered() == null) {
1197 return -1;
1198 }
1199 return artifact1.getWhenGathered().compareTo(artifact2.getWhenGathered());
1200 }
1201 }
1202
1203 @Override
1204 public List<ArtifactMetadata> getArtifacts(RepositorySession session, String repoId)
1205 throws MetadataRepositoryException {
1206 try {
1207 List<ArtifactMetadata> artifacts = new ArrayList<>();
1208 for (String ns : getRootNamespaces(session, repoId)) {
1209 getArtifacts(session, artifacts, repoId, ns);
1210 }
1211 return artifacts;
1212 } catch (MetadataResolutionException e) {
1213 throw new MetadataRepositoryException(e.getMessage(), e);
1214 }
1215 }
1216
1217 private class ArtifactCoordinates {
1218 final String namespace;
1219 final String project;
1220 final String version;
1221
1222 public ArtifactCoordinates(String namespace, String project, String version) {
1223 this.namespace = namespace;
1224 this.project = project;
1225 this.version = version;
1226 }
1227
1228 public String getNamespace( )
1229 {
1230 return namespace;
1231 }
1232
1233 public String getProject( )
1234 {
1235 return project;
1236 }
1237
1238 public String getVersion( )
1239 {
1240 return version;
1241 }
1242 }
1243
1244 @Override
1245 public Stream<ArtifactMetadata> getArtifactStream( final RepositorySession session, final String repositoryId,
1246 QueryParameter queryParameter ) throws MetadataResolutionException
1247 {
1248
1249 return getAllNamespacesStream( session, repositoryId ).filter( Objects::nonNull ).flatMap( ns ->
1250 {
1251 try
1252 {
1253 return getProjects( session, repositoryId, ns ).stream( ).map( proj ->
1254 new ArtifactCoordinates( ns, proj, null ) );
1255 }
1256 catch ( MetadataResolutionException e )
1257 {
1258 return null;
1259 }
1260 }
1261 ).filter( Objects::nonNull ).flatMap( artifactCoordinates ->
1262 {
1263 try
1264 {
1265 return getProjectVersions( session, repositoryId, artifactCoordinates.getNamespace( ), artifactCoordinates.getProject( ) )
1266 .stream( ).map(version -> new ArtifactCoordinates( artifactCoordinates.getNamespace(), artifactCoordinates.getProject(), version ));
1267 }
1268 catch ( MetadataResolutionException e )
1269 {
1270 return null;
1271 }
1272 }
1273 ).filter( Objects::nonNull ).flatMap( ac ->
1274 {
1275 try
1276 {
1277 return getArtifactStream( session, repositoryId, ac.getNamespace(), ac.getProject(), ac.getVersion() );
1278 }
1279 catch ( MetadataResolutionException e )
1280 {
1281 return null;
1282 }
1283 }
1284 ).filter( Objects::nonNull );
1285 }
1286
1287 @Override
1288 public Stream<ArtifactMetadata> getArtifactStream( final RepositorySession session, final String repoId,
1289 final String namespace, final String projectId,
1290 final String projectVersion ) throws MetadataResolutionException
1291 {
1292 return getArtifacts( session, repoId, namespace, projectId, projectVersion ).stream( );
1293 }
1294
1295 private void getArtifacts(RepositorySession session, List<ArtifactMetadata> artifacts, String repoId, String ns)
1296 throws MetadataResolutionException {
1297 for (String namespace : this.getChildNamespaces(session, repoId, ns)) {
1298 getArtifacts(session, artifacts, repoId, ns + "." + namespace);
1299 }
1300
1301 for (String project : getProjects(session, repoId, ns)) {
1302 for (String version : getProjectVersions(session, repoId, ns, project)) {
1303 artifacts.addAll(getArtifacts(session, repoId, ns, project, version));
1304 }
1305 }
1306 }
1307
1308 @Override
1309 public List<ArtifactMetadata> searchArtifacts(RepositorySession session, String repositoryId, String text, boolean exact) {
1310 throw new UnsupportedOperationException("searchArtifacts not yet implemented in File backend");
1311 }
1312
1313 @Override
1314 public List<ArtifactMetadata> searchArtifacts(RepositorySession session, String repositoryId, String key, String text, boolean exact) {
1315 throw new UnsupportedOperationException("searchArtifacts not yet implemented in File backend");
1316 }
1317 }