This project has retired. For details please refer to its
Attic page.
MetadataTools xref
1 package org.apache.archiva.repository.metadata;
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.checksum.ChecksummedFile;
24 import org.apache.archiva.common.utils.FileUtils;
25 import org.apache.archiva.common.utils.PathUtil;
26 import org.apache.archiva.common.utils.VersionComparator;
27 import org.apache.archiva.common.utils.VersionUtil;
28 import org.apache.archiva.configuration.ArchivaConfiguration;
29 import org.apache.archiva.configuration.ConfigurationNames;
30 import org.apache.archiva.configuration.FileTypes;
31 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
32 import org.apache.archiva.maven2.metadata.MavenMetadataReader;
33 import org.apache.archiva.model.ArchivaRepositoryMetadata;
34 import org.apache.archiva.model.ArtifactReference;
35 import org.apache.archiva.model.Plugin;
36 import org.apache.archiva.model.ProjectReference;
37 import org.apache.archiva.model.SnapshotVersion;
38 import org.apache.archiva.model.VersionedReference;
39 import org.apache.archiva.redback.components.registry.Registry;
40 import org.apache.archiva.redback.components.registry.RegistryListener;
41 import org.apache.archiva.repository.ContentNotFoundException;
42 import org.apache.archiva.repository.LayoutException;
43 import org.apache.archiva.repository.ManagedRepositoryContent;
44 import org.apache.archiva.repository.RemoteRepositoryContent;
45 import org.apache.archiva.xml.XMLException;
46 import org.apache.commons.collections4.CollectionUtils;
47 import org.apache.commons.lang.StringUtils;
48 import org.apache.commons.lang.math.NumberUtils;
49 import org.apache.commons.lang.time.DateUtils;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52 import org.springframework.stereotype.Service;
53
54 import javax.annotation.PostConstruct;
55 import javax.inject.Inject;
56 import javax.inject.Named;
57 import java.io.IOException;
58 import java.nio.file.Files;
59 import java.nio.file.Path;
60 import java.nio.file.Paths;
61 import java.text.ParseException;
62 import java.text.SimpleDateFormat;
63 import java.util.ArrayList;
64 import java.util.Arrays;
65 import java.util.Calendar;
66 import java.util.Collection;
67 import java.util.Collections;
68 import java.util.Date;
69 import java.util.HashMap;
70 import java.util.HashSet;
71 import java.util.Iterator;
72 import java.util.LinkedHashSet;
73 import java.util.List;
74 import java.util.Map;
75 import java.util.Set;
76 import java.util.regex.Matcher;
77 import java.util.stream.Stream;
78
79
80
81
82
83
84 @Service( "metadataTools#default" )
85 public class MetadataTools
86 implements RegistryListener
87 {
88 private Logger log = LoggerFactory.getLogger( getClass() );
89
90 public static final String MAVEN_METADATA = "maven-metadata.xml";
91
92 public static final String MAVEN_ARCHETYPE_CATALOG ="archetype-catalog.xml";
93
94 private static final char PATH_SEPARATOR = '/';
95
96 private static final char GROUP_SEPARATOR = '.';
97
98
99
100
101 @Inject
102 @Named( value = "archivaConfiguration#default" )
103 private ArchivaConfiguration configuration;
104
105
106
107
108 @Inject
109 @Named( value = "fileTypes" )
110 private FileTypes filetypes;
111
112 private List<ChecksumAlgorithm> algorithms = Arrays.asList(ChecksumAlgorithm.SHA256, ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 );
113
114 private List<String> artifactPatterns;
115
116 private Map<String, Set<String>> proxies;
117
118 private static final char NUMS[] = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
119
120 private SimpleDateFormat lastUpdatedFormat;
121
122 public MetadataTools()
123 {
124 lastUpdatedFormat = new SimpleDateFormat( "yyyyMMddHHmmss" );
125 lastUpdatedFormat.setTimeZone( DateUtils.UTC_TIME_ZONE );
126 }
127
128 @Override
129 public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
130 {
131 if ( ConfigurationNames.isProxyConnector( propertyName ) )
132 {
133 initConfigVariables();
134 }
135 }
136
137 @Override
138 public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
139 {
140
141 }
142
143
144
145
146
147
148
149
150 public Set<String> gatherSnapshotVersions( ManagedRepositoryContent managedRepository,
151 VersionedReference reference )
152 throws LayoutException, IOException, ContentNotFoundException
153 {
154 Set<String> foundVersions = managedRepository.getVersions( reference );
155
156
157
158
159
160 Set<String> proxiedRepoIds = this.proxies.get( managedRepository.getId() );
161
162 if ( CollectionUtils.isNotEmpty( proxiedRepoIds ) )
163 {
164 String baseVersion = VersionUtil.getBaseVersion( reference.getVersion() );
165 baseVersion = baseVersion.substring( 0, baseVersion.indexOf( VersionUtil.SNAPSHOT ) - 1 );
166
167
168 Iterator<String> it = proxiedRepoIds.iterator();
169 while ( it.hasNext() )
170 {
171 String proxyId = it.next();
172
173 ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata( managedRepository, reference, proxyId );
174 if ( proxyMetadata == null )
175 {
176
177 continue;
178 }
179
180
181 SnapshotVersion snapshot = proxyMetadata.getSnapshotVersion();
182 if ( snapshot != null )
183 {
184 String timestamp = snapshot.getTimestamp();
185 int buildNumber = snapshot.getBuildNumber();
186
187
188 if ( StringUtils.isNotBlank( timestamp ) && ( buildNumber > 0 ) )
189 {
190 foundVersions.add( baseVersion + "-" + timestamp + "-" + buildNumber );
191 }
192 }
193 }
194 }
195
196 return foundVersions;
197 }
198
199
200
201
202
203
204
205 public VersionedReference toVersionedReference( String path )
206 throws RepositoryMetadataException
207 {
208 if ( !path.endsWith( "/" + MAVEN_METADATA ) )
209 {
210 throw new RepositoryMetadataException( "Cannot convert to versioned reference, not a metadata file. " );
211 }
212
213 VersionedReference reference = new VersionedReference();
214
215 String normalizedPath = StringUtils.replace( path, "\\", "/" );
216 String pathParts[] = StringUtils.split( normalizedPath, '/' );
217
218 int versionOffset = pathParts.length - 2;
219 int artifactIdOffset = versionOffset - 1;
220 int groupIdEnd = artifactIdOffset - 1;
221
222 reference.setVersion( pathParts[versionOffset] );
223
224 if ( !hasNumberAnywhere( reference.getVersion() ) )
225 {
226
227 throw new RepositoryMetadataException(
228 "Not a versioned reference, as version id on path has no number in it." );
229 }
230
231 reference.setArtifactId( pathParts[artifactIdOffset] );
232
233 StringBuilder gid = new StringBuilder();
234 for ( int i = 0; i <= groupIdEnd; i++ )
235 {
236 if ( i > 0 )
237 {
238 gid.append( "." );
239 }
240 gid.append( pathParts[i] );
241 }
242
243 reference.setGroupId( gid.toString() );
244
245 return reference;
246 }
247
248 private boolean hasNumberAnywhere( String version )
249 {
250 return StringUtils.indexOfAny( version, NUMS ) != ( -1 );
251 }
252
253 public ProjectReference toProjectReference( String path )
254 throws RepositoryMetadataException
255 {
256 if ( !path.endsWith( "/" + MAVEN_METADATA ) )
257 {
258 throw new RepositoryMetadataException( "Cannot convert to versioned reference, not a metadata file. " );
259 }
260
261 ProjectReference reference = new ProjectReference();
262
263 String normalizedPath = StringUtils.replace( path, "\\", "/" );
264 String pathParts[] = StringUtils.split( normalizedPath, '/' );
265
266
267
268 int artifactIdOffset = pathParts.length - 2;
269 int groupIdEnd = artifactIdOffset - 1;
270
271 reference.setArtifactId( pathParts[artifactIdOffset] );
272
273 StringBuilder gid = new StringBuilder();
274 for ( int i = 0; i <= groupIdEnd; i++ )
275 {
276 if ( i > 0 )
277 {
278 gid.append( "." );
279 }
280 gid.append( pathParts[i] );
281 }
282
283 reference.setGroupId( gid.toString() );
284
285 return reference;
286 }
287
288
289
290 public String toPath( ProjectReference reference )
291 {
292 StringBuilder path = new StringBuilder();
293
294 path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
295 path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
296 path.append( MAVEN_METADATA );
297
298 return path.toString();
299 }
300
301 public String toPath( VersionedReference reference )
302 {
303 StringBuilder path = new StringBuilder();
304
305 path.append( formatAsDirectory( reference.getGroupId() ) ).append( PATH_SEPARATOR );
306 path.append( reference.getArtifactId() ).append( PATH_SEPARATOR );
307 if ( reference.getVersion() != null )
308 {
309
310 path.append( VersionUtil.getBaseVersion( reference.getVersion() ) ).append( PATH_SEPARATOR );
311 }
312 path.append( MAVEN_METADATA );
313
314 return path.toString();
315 }
316
317 private String formatAsDirectory( String directory )
318 {
319 return directory.replace( GROUP_SEPARATOR, PATH_SEPARATOR );
320 }
321
322
323
324
325
326
327
328
329 public String getRepositorySpecificName( RemoteRepositoryContent repository, String path )
330 {
331 return getRepositorySpecificName( repository.getId(), path );
332 }
333
334
335
336
337
338
339
340
341 public String getRepositorySpecificName( String proxyId, String path )
342 {
343 StringBuilder ret = new StringBuilder();
344
345 int idx = path.lastIndexOf( '/' );
346 if ( idx > 0 )
347 {
348 ret.append( path.substring( 0, idx + 1 ) );
349 }
350
351
352 ret.append( "maven-metadata-" ).append( proxyId ).append( ".xml" );
353
354 return ret.toString();
355 }
356
357 @PostConstruct
358 public void initialize()
359 {
360 this.artifactPatterns = new ArrayList<>();
361 this.proxies = new HashMap<>();
362 initConfigVariables();
363
364 configuration.addChangeListener( this );
365 }
366
367 public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
368 ProjectReference reference, String proxyId )
369 {
370 String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
371 Path metadataFile = Paths.get( managedRepository.getRepoRoot(), metadataPath );
372
373 if ( !Files.exists(metadataFile) || !Files.isRegularFile( metadataFile ))
374 {
375
376 return null;
377 }
378
379 try
380 {
381 return MavenMetadataReader.read( metadataFile );
382 }
383 catch ( XMLException e )
384 {
385
386
387 log.warn( "Unable to read metadata: {}", metadataFile.toAbsolutePath(), e );
388 return null;
389 }
390 }
391
392 public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
393 String logicalResource, String proxyId )
394 {
395 String metadataPath = getRepositorySpecificName( proxyId, logicalResource );
396 Path metadataFile = Paths.get( managedRepository.getRepoRoot(), metadataPath );
397
398 if ( !Files.exists(metadataFile) || !Files.isRegularFile( metadataFile))
399 {
400
401 return null;
402 }
403
404 try
405 {
406 return MavenMetadataReader.read( metadataFile );
407 }
408 catch ( XMLException e )
409 {
410
411
412 log.warn( "Unable to read metadata: {}", metadataFile.toAbsolutePath(), e );
413 return null;
414 }
415 }
416
417 public ArchivaRepositoryMetadata readProxyMetadata( ManagedRepositoryContent managedRepository,
418 VersionedReference reference, String proxyId )
419 {
420 String metadataPath = getRepositorySpecificName( proxyId, toPath( reference ) );
421 Path metadataFile = Paths.get( managedRepository.getRepoRoot(), metadataPath );
422
423 if ( !Files.exists(metadataFile) || !Files.isRegularFile(metadataFile))
424 {
425
426 return null;
427 }
428
429 try
430 {
431 return MavenMetadataReader.read( metadataFile );
432 }
433 catch ( XMLException e )
434 {
435
436
437 log.warn( "Unable to read metadata: {}", metadataFile.toAbsolutePath(), e );
438 return null;
439 }
440 }
441
442 public void updateMetadata( ManagedRepositoryContent managedRepository, String logicalResource )
443 throws RepositoryMetadataException
444 {
445 final Path metadataFile = Paths.get( managedRepository.getRepoRoot(), logicalResource );
446 ArchivaRepositoryMetadata metadata = null;
447
448
449 List<ArchivaRepositoryMetadata> metadatas =
450 getMetadatasForManagedRepository( managedRepository, logicalResource );
451 for ( ArchivaRepositoryMetadata proxiedMetadata : metadatas )
452 {
453 if ( metadata == null )
454 {
455 metadata = proxiedMetadata;
456 continue;
457 }
458 metadata = RepositoryMetadataMerge.merge( metadata, proxiedMetadata );
459 }
460
461 if ( metadata == null )
462 {
463 log.debug( "No metadata to update for {}", logicalResource );
464 return;
465 }
466
467 Set<String> availableVersions = new HashSet<String>();
468 List<String> metadataAvailableVersions = metadata.getAvailableVersions();
469 if ( metadataAvailableVersions != null )
470 {
471 availableVersions.addAll( metadataAvailableVersions );
472 }
473 availableVersions = findPossibleVersions( availableVersions, metadataFile.getParent() );
474
475 if ( availableVersions.size() > 0 )
476 {
477 updateMetadataVersions( availableVersions, metadata );
478 }
479
480 RepositoryMetadataWriter.write( metadata, metadataFile );
481
482 ChecksummedFile checksum = new ChecksummedFile( metadataFile );
483 checksum.fixChecksums( algorithms );
484 }
485
486
487
488
489
490
491
492
493 private Set<String> findPossibleVersions( Set<String> versions, Path metadataParentDirectory )
494 {
495
496 Set<String> result = new HashSet<String>( versions );
497
498 try (Stream<Path> stream = Files.list( metadataParentDirectory )) {
499 stream.filter( Files::isDirectory ).filter(
500 p ->
501 {
502 try(Stream<Path> substream = Files.list(p))
503 {
504 return substream.anyMatch( f -> Files.isRegularFile( f ) && f.toString().endsWith( ".pom" ));
505 }
506 catch ( IOException e )
507 {
508 return false;
509 }
510 }
511 ).forEach(
512 p -> result.add(p.getFileName().toString())
513 );
514 } catch (IOException e) {
515
516 }
517 return result;
518 }
519
520 private List<ArchivaRepositoryMetadata> getMetadatasForManagedRepository(
521 ManagedRepositoryContent managedRepository, String logicalResource )
522 {
523 List<ArchivaRepositoryMetadata> metadatas = new ArrayList<>();
524 Path file = Paths.get( managedRepository.getRepoRoot(), logicalResource );
525 if ( Files.exists(file) )
526 {
527 try
528 {
529 ArchivaRepositoryMetadata existingMetadata = MavenMetadataReader.read( file );
530 if ( existingMetadata != null )
531 {
532 metadatas.add( existingMetadata );
533 }
534 }
535 catch ( XMLException e )
536 {
537 log.debug( "Could not read metadata at {}. Metadata will be removed.", file.toAbsolutePath() );
538 FileUtils.deleteQuietly( file );
539 }
540 }
541
542 Set<String> proxyIds = proxies.get( managedRepository.getId() );
543 if ( proxyIds != null )
544 {
545 for ( String proxyId : proxyIds )
546 {
547 ArchivaRepositoryMetadata proxyMetadata =
548 readProxyMetadata( managedRepository, logicalResource, proxyId );
549 if ( proxyMetadata != null )
550 {
551 metadatas.add( proxyMetadata );
552 }
553 }
554 }
555
556 return metadatas;
557 }
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577 public void updateMetadata( ManagedRepositoryContent managedRepository, ProjectReference reference )
578 throws LayoutException, RepositoryMetadataException, IOException, ContentNotFoundException
579 {
580 Path metadataFile = Paths.get( managedRepository.getRepoRoot(), toPath( reference ) );
581
582 long lastUpdated = getExistingLastUpdated( metadataFile );
583
584 ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
585 metadata.setGroupId( reference.getGroupId() );
586 metadata.setArtifactId( reference.getArtifactId() );
587
588
589 Set<String> allVersions = managedRepository.getVersions( reference );
590
591
592
593
594 Set<Plugin> allPlugins;
595 if ( Files.exists(metadataFile))
596 {
597 try
598 {
599 allPlugins = new LinkedHashSet<Plugin>( MavenMetadataReader.read( metadataFile ).getPlugins() );
600 }
601 catch ( XMLException e )
602 {
603 throw new RepositoryMetadataException( e.getMessage(), e );
604 }
605 }
606 else
607 {
608 allPlugins = new LinkedHashSet<Plugin>();
609 }
610
611
612 Set<String> proxiedRepoIds = this.proxies.get( managedRepository.getId() );
613
614 if ( CollectionUtils.isNotEmpty( proxiedRepoIds ) )
615 {
616
617 Iterator<String> it = proxiedRepoIds.iterator();
618 while ( it.hasNext() )
619 {
620 String proxyId = it.next();
621
622 ArchivaRepositoryMetadata proxyMetadata = readProxyMetadata( managedRepository, reference, proxyId );
623 if ( proxyMetadata != null )
624 {
625 allVersions.addAll( proxyMetadata.getAvailableVersions() );
626 allPlugins.addAll( proxyMetadata.getPlugins() );
627 long proxyLastUpdated = getLastUpdated( proxyMetadata );
628
629 lastUpdated = Math.max( lastUpdated, proxyLastUpdated );
630 }
631 }
632 }
633
634 if ( !allVersions.isEmpty() )
635 {
636 updateMetadataVersions( allVersions, metadata );
637 }
638 else
639 {
640
641 metadata.setPlugins( new ArrayList<>( allPlugins ) );
642
643
644 metadata.setGroupId( metadata.getGroupId() + "." + metadata.getArtifactId() );
645 metadata.setArtifactId( null );
646 }
647
648 if ( lastUpdated > 0 )
649 {
650 metadata.setLastUpdatedTimestamp( toLastUpdatedDate( lastUpdated ) );
651 }
652
653
654 RepositoryMetadataWriter.write( metadata, metadataFile );
655 ChecksummedFile checksum = new ChecksummedFile( metadataFile );
656 checksum.fixChecksums( algorithms );
657 }
658
659 private void updateMetadataVersions( Collection<String> allVersions, ArchivaRepositoryMetadata metadata )
660 {
661
662 List<String> sortedVersions = new ArrayList<>( allVersions );
663 Collections.sort( sortedVersions, VersionComparator.getInstance() );
664
665
666 List<String> releasedVersions = new ArrayList<>();
667 List<String> snapshotVersions = new ArrayList<>();
668
669 for ( String version : sortedVersions )
670 {
671 if ( VersionUtil.isSnapshot( version ) )
672 {
673 snapshotVersions.add( version );
674 }
675 else
676 {
677 releasedVersions.add( version );
678 }
679 }
680
681 Collections.sort( releasedVersions, VersionComparator.getInstance() );
682 Collections.sort( snapshotVersions, VersionComparator.getInstance() );
683
684 String latestVersion = sortedVersions.get( sortedVersions.size() - 1 );
685 String releaseVersion = null;
686
687 if ( CollectionUtils.isNotEmpty( releasedVersions ) )
688 {
689 releaseVersion = releasedVersions.get( releasedVersions.size() - 1 );
690 }
691
692
693 metadata.setAvailableVersions( sortedVersions );
694
695 metadata.setLatestVersion( latestVersion );
696 metadata.setReleasedVersion( releaseVersion );
697 }
698
699 private Date toLastUpdatedDate( long lastUpdated )
700 {
701 Calendar cal = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
702 cal.setTimeInMillis( lastUpdated );
703
704 return cal.getTime();
705 }
706
707 private long toLastUpdatedLong( String timestampString )
708 {
709 try
710 {
711 Date date = lastUpdatedFormat.parse( timestampString );
712 Calendar cal = Calendar.getInstance( DateUtils.UTC_TIME_ZONE );
713 cal.setTime( date );
714
715 return cal.getTimeInMillis();
716 }
717 catch ( ParseException e )
718 {
719 return 0;
720 }
721 }
722
723 private long getLastUpdated( ArchivaRepositoryMetadata metadata )
724 {
725 if ( metadata == null )
726 {
727
728 return 0;
729 }
730
731 try
732 {
733 String lastUpdated = metadata.getLastUpdated();
734 if ( StringUtils.isBlank( lastUpdated ) )
735 {
736
737 return 0;
738 }
739
740 Date lastUpdatedDate = lastUpdatedFormat.parse( lastUpdated );
741 return lastUpdatedDate.getTime();
742 }
743 catch ( ParseException e )
744 {
745
746 return 0;
747 }
748 }
749
750 private long getExistingLastUpdated( Path metadataFile )
751 {
752 if ( !Files.exists(metadataFile) )
753 {
754
755 return 0;
756 }
757
758 try
759 {
760 ArchivaRepositoryMetadata metadata = MavenMetadataReader.read( metadataFile );
761
762 return getLastUpdated( metadata );
763 }
764 catch ( XMLException e )
765 {
766
767 return 0;
768 }
769 }
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787 public void updateMetadata( ManagedRepositoryContent managedRepository, VersionedReference reference )
788 throws LayoutException, RepositoryMetadataException, IOException, ContentNotFoundException
789 {
790 Path metadataFile = Paths.get( managedRepository.getRepoRoot(), toPath( reference ) );
791
792 long lastUpdated = getExistingLastUpdated( metadataFile );
793
794 ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
795 metadata.setGroupId( reference.getGroupId() );
796 metadata.setArtifactId( reference.getArtifactId() );
797
798 if ( VersionUtil.isSnapshot( reference.getVersion() ) )
799 {
800
801 metadata.setVersion( VersionUtil.getBaseVersion( reference.getVersion() ) );
802
803
804
805 Set<String> snapshotVersions = gatherSnapshotVersions( managedRepository, reference );
806
807 if ( snapshotVersions.isEmpty() )
808 {
809 throw new ContentNotFoundException(
810 "No snapshot versions found on reference [" + VersionedReference.toKey( reference ) + "]." );
811 }
812
813
814 List<String> sortedVersions = new ArrayList<>();
815 sortedVersions.addAll( snapshotVersions );
816 Collections.sort( sortedVersions, new VersionComparator() );
817
818 String latestVersion = sortedVersions.get( sortedVersions.size() - 1 );
819
820 if ( VersionUtil.isUniqueSnapshot( latestVersion ) )
821 {
822
823
824
825 Matcher m = VersionUtil.UNIQUE_SNAPSHOT_PATTERN.matcher( latestVersion );
826 if ( m.matches() )
827 {
828 metadata.setSnapshotVersion( new SnapshotVersion() );
829 int buildNumber = NumberUtils.toInt( m.group( 3 ), -1 );
830 metadata.getSnapshotVersion().setBuildNumber( buildNumber );
831
832 Matcher mtimestamp = VersionUtil.TIMESTAMP_PATTERN.matcher( m.group( 2 ) );
833 if ( mtimestamp.matches() )
834 {
835 String tsDate = mtimestamp.group( 1 );
836 String tsTime = mtimestamp.group( 2 );
837
838 long snapshotLastUpdated = toLastUpdatedLong( tsDate + tsTime );
839
840 lastUpdated = Math.max( lastUpdated, snapshotLastUpdated );
841
842 metadata.getSnapshotVersion().setTimestamp( m.group( 2 ) );
843 }
844 }
845 }
846 else if ( VersionUtil.isGenericSnapshot( latestVersion ) )
847 {
848
849
850
851 metadata.setSnapshotVersion( new SnapshotVersion() );
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874 }
875 else
876 {
877 throw new RepositoryMetadataException(
878 "Unable to process snapshot version <" + latestVersion + "> reference <" + reference + ">" );
879 }
880 }
881 else
882 {
883
884 metadata.setVersion( reference.getVersion() );
885 }
886
887
888 if ( lastUpdated > 0 )
889 {
890 metadata.setLastUpdatedTimestamp( toLastUpdatedDate( lastUpdated ) );
891 }
892
893
894 RepositoryMetadataWriter.write( metadata, metadataFile );
895 ChecksummedFile checksum = new ChecksummedFile( metadataFile );
896 checksum.fixChecksums( algorithms );
897 }
898
899 private void initConfigVariables()
900 {
901 synchronized ( this.artifactPatterns )
902 {
903 this.artifactPatterns.clear();
904
905 this.artifactPatterns.addAll( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
906 }
907
908 synchronized ( proxies )
909 {
910 this.proxies.clear();
911
912 List<ProxyConnectorConfiguration> proxyConfigs = configuration.getConfiguration().getProxyConnectors();
913 for ( ProxyConnectorConfiguration proxyConfig : proxyConfigs )
914 {
915 String key = proxyConfig.getSourceRepoId();
916
917 Set<String> remoteRepoIds = this.proxies.get( key );
918
919 if ( remoteRepoIds == null )
920 {
921 remoteRepoIds = new HashSet<String>();
922 }
923
924 remoteRepoIds.add( proxyConfig.getTargetRepoId() );
925
926 this.proxies.put( key, remoteRepoIds );
927 }
928 }
929 }
930
931
932
933
934
935
936
937
938
939
940
941 public ArtifactReference getFirstArtifact( ManagedRepositoryContent managedRepository,
942 VersionedReference reference )
943 throws LayoutException, IOException
944 {
945 String path = toPath( reference );
946
947 int idx = path.lastIndexOf( '/' );
948 if ( idx > 0 )
949 {
950 path = path.substring( 0, idx );
951 }
952
953 Path repoDir = Paths.get( managedRepository.getRepoRoot(), path );
954
955 if ( !Files.exists(repoDir))
956 {
957 throw new IOException( "Unable to gather the list of snapshot versions on a non-existant directory: "
958 + repoDir.toAbsolutePath() );
959 }
960
961 if ( !Files.isDirectory( repoDir ))
962 {
963 throw new IOException(
964 "Unable to gather the list of snapshot versions on a non-directory: " + repoDir.toAbsolutePath() );
965 }
966
967 try(Stream<Path> stream = Files.list(repoDir)) {
968 String result = stream.filter( Files::isRegularFile ).map( path1 ->
969 PathUtil.getRelative( managedRepository.getRepoRoot(), path1 )
970 ).filter( filetypes::matchesArtifactPattern ).findFirst().orElse( null );
971 if (result!=null) {
972 return managedRepository.toArtifactReference( result );
973 }
974 }
975
976 return null;
977 }
978
979 public ArchivaConfiguration getConfiguration()
980 {
981 return configuration;
982 }
983
984 public void setConfiguration( ArchivaConfiguration configuration )
985 {
986 this.configuration = configuration;
987 }
988
989 public FileTypes getFiletypes()
990 {
991 return filetypes;
992 }
993
994 public void setFiletypes( FileTypes filetypes )
995 {
996 this.filetypes = filetypes;
997 }
998 }