001package org.apache.archiva.metadata.repository.file; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.archiva.configuration.ArchivaConfiguration; 023import org.apache.archiva.configuration.ManagedRepositoryConfiguration; 024import org.apache.archiva.metadata.model.ArtifactMetadata; 025import org.apache.archiva.metadata.model.CiManagement; 026import org.apache.archiva.metadata.model.Dependency; 027import org.apache.archiva.metadata.model.IssueManagement; 028import org.apache.archiva.metadata.model.License; 029import org.apache.archiva.metadata.model.MailingList; 030import org.apache.archiva.metadata.model.MetadataFacet; 031import org.apache.archiva.metadata.model.MetadataFacetFactory; 032import org.apache.archiva.metadata.model.Organization; 033import org.apache.archiva.metadata.model.ProjectMetadata; 034import org.apache.archiva.metadata.model.ProjectVersionMetadata; 035import org.apache.archiva.metadata.model.ProjectVersionReference; 036import org.apache.archiva.metadata.model.Scm; 037import org.apache.archiva.metadata.repository.MetadataRepository; 038import org.apache.archiva.metadata.repository.MetadataRepositoryException; 039import org.apache.archiva.metadata.repository.MetadataResolutionException; 040import org.apache.commons.io.FileUtils; 041import org.slf4j.Logger; 042import org.slf4j.LoggerFactory; 043 044import java.io.File; 045import java.io.FileNotFoundException; 046import java.io.IOException; 047import java.io.InputStream; 048import java.io.OutputStream; 049import java.nio.file.Files; 050import java.nio.file.NoSuchFileException; 051import java.util.ArrayList; 052import java.util.Arrays; 053import java.util.Collection; 054import java.util.Collections; 055import java.util.Comparator; 056import java.util.Date; 057import java.util.HashMap; 058import java.util.HashSet; 059import java.util.LinkedHashSet; 060import java.util.List; 061import java.util.Map; 062import java.util.Properties; 063import java.util.Set; 064import java.util.StringTokenizer; 065 066public class FileMetadataRepository 067 implements MetadataRepository 068{ 069 private final Map<String, MetadataFacetFactory> metadataFacetFactories; 070 071 private final ArchivaConfiguration configuration; 072 073 private Logger log = LoggerFactory.getLogger( FileMetadataRepository.class ); 074 075 private static final String PROJECT_METADATA_KEY = "project-metadata"; 076 077 private static final String PROJECT_VERSION_METADATA_KEY = "version-metadata"; 078 079 private static final String NAMESPACE_METADATA_KEY = "namespace-metadata"; 080 081 private static final String METADATA_KEY = "metadata"; 082 083 public FileMetadataRepository( Map<String, MetadataFacetFactory> metadataFacetFactories, 084 ArchivaConfiguration configuration ) 085 { 086 this.metadataFacetFactories = metadataFacetFactories; 087 this.configuration = configuration; 088 } 089 090 private File getBaseDirectory( String repoId ) 091 throws IOException 092 { 093 // TODO: should be configurable, like the index 094 ManagedRepositoryConfiguration managedRepositoryConfiguration = 095 configuration.getConfiguration().getManagedRepositoriesAsMap().get( repoId ); 096 if ( managedRepositoryConfiguration == null ) 097 { 098 return Files.createTempDirectory( repoId ).toFile(); 099 } 100 String basedir = managedRepositoryConfiguration.getLocation(); 101 return new File( basedir, ".archiva" ); 102 } 103 104 private File getDirectory( String repoId ) 105 throws IOException 106 { 107 return new File( getBaseDirectory( repoId ), "content" ); 108 } 109 110 @Override 111 public void updateProject( String repoId, ProjectMetadata project ) 112 { 113 updateProject( repoId, project.getNamespace(), project.getId() ); 114 } 115 116 private void updateProject( String repoId, String namespace, String id ) 117 { 118 // TODO: this is a more braindead implementation than we would normally expect, for prototyping purposes 119 updateNamespace( repoId, namespace ); 120 121 try 122 { 123 File namespaceDirectory = new File( getDirectory( repoId ), namespace ); 124 Properties properties = new Properties(); 125 properties.setProperty( "namespace", namespace ); 126 properties.setProperty( "id", id ); 127 writeProperties( properties, new File( namespaceDirectory, id ), PROJECT_METADATA_KEY ); 128 } 129 catch ( IOException e ) 130 { 131 // TODO! 132 log.error( e.getMessage(), e ); 133 } 134 } 135 136 @Override 137 public void updateProjectVersion( String repoId, String namespace, String projectId, 138 ProjectVersionMetadata versionMetadata ) 139 { 140 141 try 142 { 143 updateProject( repoId, namespace, projectId ); 144 145 File directory = 146 new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + versionMetadata.getId() ); 147 148 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 149 // remove properties that are not references or artifacts 150 for ( Object key : new ArrayList( properties.keySet() ) ) 151 { 152 String name = (String) key; 153 if ( !name.contains( ":" ) && !name.equals( "facetIds" ) ) 154 { 155 properties.remove( name ); 156 } 157 158 // clear the facet contents so old properties are no longer written 159 clearMetadataFacetProperties( versionMetadata.getFacetList(), properties, "" ); 160 } 161 properties.setProperty( "id", versionMetadata.getId() ); 162 setProperty( properties, "name", versionMetadata.getName() ); 163 setProperty( properties, "description", versionMetadata.getDescription() ); 164 setProperty( properties, "url", versionMetadata.getUrl() ); 165 setProperty( properties, "incomplete", String.valueOf( versionMetadata.isIncomplete() ) ); 166 if ( versionMetadata.getScm() != null ) 167 { 168 setProperty( properties, "scm.connection", versionMetadata.getScm().getConnection() ); 169 setProperty( properties, "scm.developerConnection", versionMetadata.getScm().getDeveloperConnection() ); 170 setProperty( properties, "scm.url", versionMetadata.getScm().getUrl() ); 171 } 172 if ( versionMetadata.getCiManagement() != null ) 173 { 174 setProperty( properties, "ci.system", versionMetadata.getCiManagement().getSystem() ); 175 setProperty( properties, "ci.url", versionMetadata.getCiManagement().getUrl() ); 176 } 177 if ( versionMetadata.getIssueManagement() != null ) 178 { 179 setProperty( properties, "issue.system", versionMetadata.getIssueManagement().getSystem() ); 180 setProperty( properties, "issue.url", versionMetadata.getIssueManagement().getUrl() ); 181 } 182 if ( versionMetadata.getOrganization() != null ) 183 { 184 setProperty( properties, "org.name", versionMetadata.getOrganization().getName() ); 185 setProperty( properties, "org.url", versionMetadata.getOrganization().getUrl() ); 186 } 187 int i = 0; 188 for ( License license : versionMetadata.getLicenses() ) 189 { 190 setProperty( properties, "license." + i + ".name", license.getName() ); 191 setProperty( properties, "license." + i + ".url", license.getUrl() ); 192 i++; 193 } 194 i = 0; 195 for ( MailingList mailingList : versionMetadata.getMailingLists() ) 196 { 197 setProperty( properties, "mailingList." + i + ".archive", mailingList.getMainArchiveUrl() ); 198 setProperty( properties, "mailingList." + i + ".name", mailingList.getName() ); 199 setProperty( properties, "mailingList." + i + ".post", mailingList.getPostAddress() ); 200 setProperty( properties, "mailingList." + i + ".unsubscribe", mailingList.getUnsubscribeAddress() ); 201 setProperty( properties, "mailingList." + i + ".subscribe", mailingList.getSubscribeAddress() ); 202 setProperty( properties, "mailingList." + i + ".otherArchives", 203 join( mailingList.getOtherArchives() ) ); 204 i++; 205 } 206 i = 0; 207 ProjectVersionReference reference = new ProjectVersionReference(); 208 reference.setNamespace( namespace ); 209 reference.setProjectId( projectId ); 210 reference.setProjectVersion( versionMetadata.getId() ); 211 reference.setReferenceType( ProjectVersionReference.ReferenceType.DEPENDENCY ); 212 for ( Dependency dependency : versionMetadata.getDependencies() ) 213 { 214 setProperty( properties, "dependency." + i + ".classifier", dependency.getClassifier() ); 215 setProperty( properties, "dependency." + i + ".scope", dependency.getScope() ); 216 setProperty( properties, "dependency." + i + ".systemPath", dependency.getSystemPath() ); 217 setProperty( properties, "dependency." + i + ".artifactId", dependency.getArtifactId() ); 218 setProperty( properties, "dependency." + i + ".groupId", dependency.getGroupId() ); 219 setProperty( properties, "dependency." + i + ".version", dependency.getVersion() ); 220 setProperty( properties, "dependency." + i + ".type", dependency.getType() ); 221 setProperty( properties, "dependency." + i + ".optional", String.valueOf( dependency.isOptional() ) ); 222 223 updateProjectReference( repoId, dependency.getGroupId(), dependency.getArtifactId(), 224 dependency.getVersion(), reference ); 225 226 i++; 227 } 228 Set<String> facetIds = new LinkedHashSet<String>( versionMetadata.getFacetIds() ); 229 facetIds.addAll( Arrays.asList( properties.getProperty( "facetIds", "" ).split( "," ) ) ); 230 properties.setProperty( "facetIds", join( facetIds ) ); 231 232 updateProjectVersionFacets( versionMetadata, properties ); 233 234 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY ); 235 } 236 catch ( IOException e ) 237 { 238 // TODO 239 log.error( e.getMessage(), e ); 240 } 241 } 242 243 private void updateProjectVersionFacets( ProjectVersionMetadata versionMetadata, Properties properties ) 244 { 245 for ( MetadataFacet facet : versionMetadata.getFacetList() ) 246 { 247 for ( Map.Entry<String, String> entry : facet.toProperties().entrySet() ) 248 { 249 properties.setProperty( facet.getFacetId() + ":" + entry.getKey(), entry.getValue() ); 250 } 251 } 252 } 253 254 private static void clearMetadataFacetProperties( Collection<MetadataFacet> facetList, Properties properties, 255 String prefix ) 256 { 257 List<Object> propsToRemove = new ArrayList<>(); 258 for ( MetadataFacet facet : facetList ) 259 { 260 for ( Object key : new ArrayList( properties.keySet() ) ) 261 { 262 String keyString = (String) key; 263 if ( keyString.startsWith( prefix + facet.getFacetId() + ":" ) ) 264 { 265 propsToRemove.add( key ); 266 } 267 } 268 } 269 270 for ( Object key : propsToRemove ) 271 { 272 properties.remove( key ); 273 } 274 } 275 276 private void updateProjectReference( String repoId, String namespace, String projectId, String projectVersion, 277 ProjectVersionReference reference ) 278 { 279 try 280 { 281 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion ); 282 283 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 284 int i = Integer.parseInt( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1; 285 setProperty( properties, "ref:lastReferenceNum", Integer.toString( i ) ); 286 setProperty( properties, "ref:reference." + i + ".namespace", reference.getNamespace() ); 287 setProperty( properties, "ref:reference." + i + ".projectId", reference.getProjectId() ); 288 setProperty( properties, "ref:reference." + i + ".projectVersion", reference.getProjectVersion() ); 289 setProperty( properties, "ref:reference." + i + ".referenceType", reference.getReferenceType().toString() ); 290 291 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY ); 292 } 293 catch ( IOException e ) 294 { 295 // TODO 296 log.error( e.getMessage(), e ); 297 } 298 } 299 300 @Override 301 public void updateNamespace( String repoId, String namespace ) 302 { 303 try 304 { 305 File namespaceDirectory = new File( getDirectory( repoId ), namespace ); 306 Properties properties = new Properties(); 307 properties.setProperty( "namespace", namespace ); 308 writeProperties( properties, namespaceDirectory, NAMESPACE_METADATA_KEY ); 309 310 } 311 catch ( IOException e ) 312 { 313 // TODO! 314 log.error( e.getMessage(), e ); 315 } 316 } 317 318 @Override 319 public List<String> getMetadataFacets( String repoId, String facetId ) 320 throws MetadataRepositoryException 321 { 322 try 323 { 324 File directory = getMetadataDirectory( repoId, facetId ); 325 List<String> facets = new ArrayList<>(); 326 recurse( facets, "", directory ); 327 return facets; 328 } 329 catch ( IOException e ) 330 { 331 throw new MetadataRepositoryException( e.getMessage(), e ); 332 } 333 } 334 335 @Override 336 public boolean hasMetadataFacet( String repositoryId, String facetId ) 337 throws MetadataRepositoryException 338 { 339 // TODO could be improved a bit 340 return !getMetadataFacets( repositoryId, facetId ).isEmpty(); 341 } 342 343 private void recurse( List<String> facets, String prefix, File directory ) 344 { 345 File[] list = directory.listFiles(); 346 if ( list != null ) 347 { 348 for ( File dir : list ) 349 { 350 if ( dir.isDirectory() ) 351 { 352 recurse( facets, prefix + "/" + dir.getName(), dir ); 353 } 354 else if ( dir.getName().equals( METADATA_KEY + ".properties" ) ) 355 { 356 facets.add( prefix.substring( 1 ) ); 357 } 358 } 359 } 360 } 361 362 @Override 363 public MetadataFacet getMetadataFacet( String repositoryId, String facetId, String name ) 364 { 365 Properties properties; 366 try 367 { 368 properties = 369 readProperties( new File( getMetadataDirectory( repositoryId, facetId ), name ), METADATA_KEY ); 370 } 371 catch ( FileNotFoundException e ) 372 { 373 return null; 374 } 375 catch ( IOException e ) 376 { 377 // TODO 378 log.error( e.getMessage(), e ); 379 return null; 380 } 381 MetadataFacet metadataFacet = null; 382 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId ); 383 if ( metadataFacetFactory != null ) 384 { 385 metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name ); 386 Map<String, String> map = new HashMap<>(); 387 for ( Object key : new ArrayList( properties.keySet() ) ) 388 { 389 String property = (String) key; 390 map.put( property, properties.getProperty( property ) ); 391 } 392 metadataFacet.fromProperties( map ); 393 } 394 return metadataFacet; 395 } 396 397 @Override 398 public void addMetadataFacet( String repositoryId, MetadataFacet metadataFacet ) 399 { 400 Properties properties = new Properties(); 401 properties.putAll( metadataFacet.toProperties() ); 402 403 try 404 { 405 File directory = 406 new File( getMetadataDirectory( repositoryId, metadataFacet.getFacetId() ), metadataFacet.getName() ); 407 writeProperties( properties, directory, METADATA_KEY ); 408 } 409 catch ( IOException e ) 410 { 411 // TODO! 412 log.error( e.getMessage(), e ); 413 } 414 } 415 416 @Override 417 public void removeMetadataFacets( String repositoryId, String facetId ) 418 throws MetadataRepositoryException 419 { 420 try 421 { 422 File dir = getMetadataDirectory( repositoryId, facetId ); 423 FileUtils.deleteDirectory( dir ); 424 } 425 catch ( IOException e ) 426 { 427 throw new MetadataRepositoryException( e.getMessage(), e ); 428 } 429 } 430 431 @Override 432 public void removeMetadataFacet( String repoId, String facetId, String name ) 433 throws MetadataRepositoryException 434 { 435 try 436 { 437 File dir = new File( getMetadataDirectory( repoId, facetId ), name ); 438 FileUtils.deleteDirectory( dir ); 439 } 440 catch ( IOException e ) 441 { 442 throw new MetadataRepositoryException( e.getMessage(), e ); 443 } 444 } 445 446 @Override 447 public List<ArtifactMetadata> getArtifactsByDateRange( String repoId, Date startTime, Date endTime ) 448 throws MetadataRepositoryException 449 { 450 try 451 { 452 // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index 453 // of this information (eg. in Lucene, as before) 454 455 List<ArtifactMetadata> artifacts = new ArrayList<>(); 456 for ( String ns : getRootNamespaces( repoId ) ) 457 { 458 getArtifactsByDateRange( artifacts, repoId, ns, startTime, endTime ); 459 } 460 Collections.sort( artifacts, new ArtifactComparator() ); 461 return artifacts; 462 } 463 catch ( MetadataResolutionException e ) 464 { 465 throw new MetadataRepositoryException( e.getMessage(), e ); 466 } 467 } 468 469 private void getArtifactsByDateRange( List<ArtifactMetadata> artifacts, String repoId, String ns, Date startTime, 470 Date endTime ) 471 throws MetadataRepositoryException 472 { 473 try 474 { 475 for ( String namespace : getNamespaces( repoId, ns ) ) 476 { 477 getArtifactsByDateRange( artifacts, repoId, ns + "." + namespace, startTime, endTime ); 478 } 479 480 for ( String project : getProjects( repoId, ns ) ) 481 { 482 for ( String version : getProjectVersions( repoId, ns, project ) ) 483 { 484 for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) ) 485 { 486 if ( startTime == null || startTime.before( artifact.getWhenGathered() ) ) 487 { 488 if ( endTime == null || endTime.after( artifact.getWhenGathered() ) ) 489 { 490 artifacts.add( artifact ); 491 } 492 } 493 } 494 } 495 } 496 } 497 catch ( MetadataResolutionException e ) 498 { 499 throw new MetadataRepositoryException( e.getMessage(), e ); 500 } 501 } 502 503 @Override 504 public Collection<ArtifactMetadata> getArtifacts( String repoId, String namespace, String projectId, 505 String projectVersion ) 506 throws MetadataResolutionException 507 { 508 try 509 { 510 Map<String, ArtifactMetadata> artifacts = new HashMap<>(); 511 512 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion ); 513 514 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 515 516 for ( Map.Entry entry : properties.entrySet() ) 517 { 518 String name = (String) entry.getKey(); 519 StringTokenizer tok = new StringTokenizer( name, ":" ); 520 if ( tok.hasMoreTokens() && "artifact".equals( tok.nextToken() ) ) 521 { 522 String field = tok.nextToken(); 523 String id = tok.nextToken(); 524 525 ArtifactMetadata artifact = artifacts.get( id ); 526 if ( artifact == null ) 527 { 528 artifact = new ArtifactMetadata(); 529 artifact.setRepositoryId( repoId ); 530 artifact.setNamespace( namespace ); 531 artifact.setProject( projectId ); 532 artifact.setProjectVersion( projectVersion ); 533 artifact.setVersion( projectVersion ); 534 artifact.setId( id ); 535 artifacts.put( id, artifact ); 536 } 537 538 String value = (String) entry.getValue(); 539 if ( "updated".equals( field ) ) 540 { 541 artifact.setFileLastModified( Long.parseLong( value ) ); 542 } 543 else if ( "size".equals( field ) ) 544 { 545 artifact.setSize( Long.valueOf( value ) ); 546 } 547 else if ( "whenGathered".equals( field ) ) 548 { 549 artifact.setWhenGathered( new Date( Long.parseLong( value ) ) ); 550 } 551 else if ( "version".equals( field ) ) 552 { 553 artifact.setVersion( value ); 554 } 555 else if ( "md5".equals( field ) ) 556 { 557 artifact.setMd5( value ); 558 } 559 else if ( "sha1".equals( field ) ) 560 { 561 artifact.setSha1( value ); 562 } 563 else if ( "facetIds".equals( field ) ) 564 { 565 if ( value.length() > 0 ) 566 { 567 String propertyPrefix = "artifact:facet:" + id + ":"; 568 for ( String facetId : value.split( "," ) ) 569 { 570 MetadataFacetFactory factory = metadataFacetFactories.get( facetId ); 571 if ( factory == null ) 572 { 573 log.error( "Attempted to load unknown artifact metadata facet: " + facetId ); 574 } 575 else 576 { 577 MetadataFacet facet = factory.createMetadataFacet(); 578 String prefix = propertyPrefix + facet.getFacetId(); 579 Map<String, String> map = new HashMap<>(); 580 for ( Object key : new ArrayList( properties.keySet() ) ) 581 { 582 String property = (String) key; 583 if ( property.startsWith( prefix ) ) 584 { 585 map.put( property.substring( prefix.length() + 1 ), 586 properties.getProperty( property ) ); 587 } 588 } 589 facet.fromProperties( map ); 590 artifact.addFacet( facet ); 591 } 592 } 593 } 594 595 updateArtifactFacets( artifact, properties ); 596 } 597 } 598 } 599 return artifacts.values(); 600 } 601 catch ( IOException e ) 602 { 603 throw new MetadataResolutionException( e.getMessage(), e ); 604 } 605 } 606 607 @Override 608 public void save() 609 { 610 // it's all instantly persisted 611 } 612 613 @Override 614 public void close() 615 { 616 // nothing additional to close 617 } 618 619 @Override 620 public void revert() 621 { 622 log.warn( "Attempted to revert a session, but the file-based repository storage doesn't support it" ); 623 } 624 625 @Override 626 public boolean canObtainAccess( Class<?> aClass ) 627 { 628 return false; 629 } 630 631 @Override 632 public <T> T obtainAccess( Class<T> aClass ) 633 { 634 throw new IllegalArgumentException( 635 "Access using " + aClass + " is not supported on the file metadata storage" ); 636 } 637 638 private void updateArtifactFacets( ArtifactMetadata artifact, Properties properties ) 639 { 640 String propertyPrefix = "artifact:facet:" + artifact.getId() + ":"; 641 for ( MetadataFacet facet : artifact.getFacetList() ) 642 { 643 for ( Map.Entry<String, String> e : facet.toProperties().entrySet() ) 644 { 645 String key = propertyPrefix + facet.getFacetId() + ":" + e.getKey(); 646 properties.setProperty( key, e.getValue() ); 647 } 648 } 649 } 650 651 @Override 652 public Collection<String> getRepositories() 653 { 654 List<String> repositories = new ArrayList<>(); 655 for ( ManagedRepositoryConfiguration managedRepositoryConfiguration : configuration.getConfiguration().getManagedRepositories() ) 656 { 657 repositories.add( managedRepositoryConfiguration.getId() ); 658 } 659 return repositories; 660 } 661 662 @Override 663 public List<ArtifactMetadata> getArtifactsByChecksum( String repositoryId, String checksum ) 664 throws MetadataRepositoryException 665 { 666 try 667 { 668 // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index 669 // of this information (eg. in Lucene, as before) 670 // alternatively, we could build a referential tree in the content repository, however it would need some levels 671 // of depth to avoid being too broad to be useful (eg. /repository/checksums/a/ab/abcdef1234567) 672 673 List<ArtifactMetadata> artifacts = new ArrayList<>(); 674 for ( String ns : getRootNamespaces( repositoryId ) ) 675 { 676 getArtifactsByChecksum( artifacts, repositoryId, ns, checksum ); 677 } 678 return artifacts; 679 } 680 catch ( MetadataResolutionException e ) 681 { 682 throw new MetadataRepositoryException( e.getMessage(), e ); 683 } 684 } 685 686 @Override 687 public void removeNamespace( String repositoryId, String project ) 688 throws MetadataRepositoryException 689 { 690 try 691 { 692 File namespaceDirectory = new File( getDirectory( repositoryId ), project ); 693 FileUtils.deleteDirectory( namespaceDirectory ); 694 //Properties properties = new Properties(); 695 //properties.setProperty( "namespace", namespace ); 696 //writeProperties( properties, namespaceDirectory, NAMESPACE_METADATA_KEY ); 697 698 } 699 catch ( IOException e ) 700 { 701 throw new MetadataRepositoryException( e.getMessage(), e ); 702 } 703 } 704 705 @Override 706 public void removeArtifact( ArtifactMetadata artifactMetadata, String baseVersion ) 707 throws MetadataRepositoryException 708 { 709 710 try 711 { 712 File directory = new File( getDirectory( artifactMetadata.getRepositoryId() ), 713 artifactMetadata.getNamespace() + "/" + artifactMetadata.getProject() + "/" 714 + baseVersion ); 715 716 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 717 718 String id = artifactMetadata.getId(); 719 720 properties.remove( "artifact:updated:" + id ); 721 properties.remove( "artifact:whenGathered:" + id ); 722 properties.remove( "artifact:size:" + id ); 723 properties.remove( "artifact:md5:" + id ); 724 properties.remove( "artifact:sha1:" + id ); 725 properties.remove( "artifact:version:" + id ); 726 properties.remove( "artifact:facetIds:" + id ); 727 728 String prefix = "artifact:facet:" + id + ":"; 729 for ( Object key : new ArrayList( properties.keySet() ) ) 730 { 731 String property = (String) key; 732 if ( property.startsWith( prefix ) ) 733 { 734 properties.remove( property ); 735 } 736 } 737 738 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY ); 739 } 740 catch ( IOException e ) 741 { 742 throw new MetadataRepositoryException( e.getMessage(), e ); 743 } 744 745 } 746 747 @Override 748 public void removeArtifact( String repoId, String namespace, String project, String version, String id ) 749 throws MetadataRepositoryException 750 { 751 try 752 { 753 File directory = new File( getDirectory( repoId ), namespace + "/" + project + "/" + version ); 754 755 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 756 757 properties.remove( "artifact:updated:" + id ); 758 properties.remove( "artifact:whenGathered:" + id ); 759 properties.remove( "artifact:size:" + id ); 760 properties.remove( "artifact:md5:" + id ); 761 properties.remove( "artifact:sha1:" + id ); 762 properties.remove( "artifact:version:" + id ); 763 properties.remove( "artifact:facetIds:" + id ); 764 765 String prefix = "artifact:facet:" + id + ":"; 766 for ( Object key : new ArrayList( properties.keySet() ) ) 767 { 768 String property = (String) key; 769 if ( property.startsWith( prefix ) ) 770 { 771 properties.remove( property ); 772 } 773 } 774 775 FileUtils.deleteDirectory( directory ); 776 //writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY ); 777 } 778 catch ( IOException e ) 779 { 780 throw new MetadataRepositoryException( e.getMessage(), e ); 781 } 782 } 783 784 /** 785 * FIXME implements this !!!! 786 * 787 * @param repositoryId 788 * @param namespace 789 * @param project 790 * @param projectVersion 791 * @param metadataFacet will remove artifacts which have this {@link MetadataFacet} using equals 792 * @throws MetadataRepositoryException 793 */ 794 @Override 795 public void removeArtifact( String repositoryId, String namespace, String project, String projectVersion, 796 MetadataFacet metadataFacet ) 797 throws MetadataRepositoryException 798 { 799 throw new UnsupportedOperationException( "not implemented" ); 800 } 801 802 @Override 803 public void removeRepository( String repoId ) 804 throws MetadataRepositoryException 805 { 806 try 807 { 808 File dir = getDirectory( repoId ); 809 FileUtils.deleteDirectory( dir ); 810 } 811 catch ( IOException e ) 812 { 813 throw new MetadataRepositoryException( e.getMessage(), e ); 814 } 815 } 816 817 private void getArtifactsByChecksum( List<ArtifactMetadata> artifacts, String repositoryId, String ns, 818 String checksum ) 819 throws MetadataRepositoryException 820 { 821 try 822 { 823 for ( String namespace : getNamespaces( repositoryId, ns ) ) 824 { 825 getArtifactsByChecksum( artifacts, repositoryId, ns + "." + namespace, checksum ); 826 } 827 828 for ( String project : getProjects( repositoryId, ns ) ) 829 { 830 for ( String version : getProjectVersions( repositoryId, ns, project ) ) 831 { 832 for ( ArtifactMetadata artifact : getArtifacts( repositoryId, ns, project, version ) ) 833 { 834 if ( checksum.equals( artifact.getMd5() ) || checksum.equals( artifact.getSha1() ) ) 835 { 836 artifacts.add( artifact ); 837 } 838 } 839 } 840 } 841 } 842 catch ( MetadataResolutionException e ) 843 { 844 throw new MetadataRepositoryException( e.getMessage(), e ); 845 } 846 } 847 848 @Override 849 public List<ArtifactMetadata> getArtifactsByProjectVersionMetadata( String key, String value, String repositoryId ) 850 throws MetadataRepositoryException 851 { 852 throw new UnsupportedOperationException( "not yet implemented in File backend" ); 853 } 854 855 @Override 856 public List<ArtifactMetadata> getArtifactsByMetadata( String key, String value, String repositoryId ) 857 throws MetadataRepositoryException 858 { 859 throw new UnsupportedOperationException( "not yet implemented in File backend" ); 860 } 861 862 @Override 863 public List<ArtifactMetadata> getArtifactsByProperty( String key, String value, String repositoryId ) 864 throws MetadataRepositoryException 865 { 866 throw new UnsupportedOperationException( "getArtifactsByProperty not yet implemented in File backend" ); 867 } 868 869 private File getMetadataDirectory( String repoId, String facetId ) 870 throws IOException 871 { 872 return new File( getBaseDirectory( repoId ), "facets/" + facetId ); 873 } 874 875 private String join( Collection<String> ids ) 876 { 877 if ( ids != null && !ids.isEmpty() ) 878 { 879 StringBuilder s = new StringBuilder(); 880 for ( String id : ids ) 881 { 882 s.append( id ); 883 s.append( "," ); 884 } 885 return s.substring( 0, s.length() - 1 ); 886 } 887 return ""; 888 } 889 890 private void setProperty( Properties properties, String name, String value ) 891 { 892 if ( value != null ) 893 { 894 properties.setProperty( name, value ); 895 } 896 } 897 898 @Override 899 public void updateArtifact( String repoId, String namespace, String projectId, String projectVersion, 900 ArtifactMetadata artifact ) 901 { 902 try 903 { 904 ProjectVersionMetadata metadata = new ProjectVersionMetadata(); 905 metadata.setId( projectVersion ); 906 updateProjectVersion( repoId, namespace, projectId, metadata ); 907 908 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion ); 909 910 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 911 912 clearMetadataFacetProperties( artifact.getFacetList(), properties, 913 "artifact:facet:" + artifact.getId() + ":" ); 914 915 String id = artifact.getId(); 916 properties.setProperty( "artifact:updated:" + id, 917 Long.toString( artifact.getFileLastModified().getTime() ) ); 918 properties.setProperty( "artifact:whenGathered:" + id, 919 Long.toString( artifact.getWhenGathered().getTime() ) ); 920 properties.setProperty( "artifact:size:" + id, Long.toString( artifact.getSize() ) ); 921 if ( artifact.getMd5() != null ) 922 { 923 properties.setProperty( "artifact:md5:" + id, artifact.getMd5() ); 924 } 925 if ( artifact.getSha1() != null ) 926 { 927 properties.setProperty( "artifact:sha1:" + id, artifact.getSha1() ); 928 } 929 properties.setProperty( "artifact:version:" + id, artifact.getVersion() ); 930 931 Set<String> facetIds = new LinkedHashSet<String>( artifact.getFacetIds() ); 932 String property = "artifact:facetIds:" + id; 933 facetIds.addAll( Arrays.asList( properties.getProperty( property, "" ).split( "," ) ) ); 934 properties.setProperty( property, join( facetIds ) ); 935 936 updateArtifactFacets( artifact, properties ); 937 938 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY ); 939 } 940 catch ( IOException e ) 941 { 942 // TODO 943 log.error( e.getMessage(), e ); 944 } 945 } 946 947 private Properties readOrCreateProperties( File directory, String propertiesKey ) 948 { 949 try 950 { 951 return readProperties( directory, propertiesKey ); 952 } 953 catch ( FileNotFoundException | NoSuchFileException e ) 954 { 955 // ignore and return new properties 956 } 957 catch ( IOException e ) 958 { 959 // TODO 960 log.error( e.getMessage(), e ); 961 } 962 return new Properties(); 963 } 964 965 private Properties readProperties( File directory, String propertiesKey ) 966 throws IOException 967 { 968 Properties properties = new Properties(); 969 try (InputStream in = Files.newInputStream( new File( directory, propertiesKey + ".properties" ).toPath() )) 970 { 971 972 properties.load( in ); 973 } 974 return properties; 975 } 976 977 @Override 978 public ProjectMetadata getProject( String repoId, String namespace, String projectId ) 979 throws MetadataResolutionException 980 { 981 try 982 { 983 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId ); 984 985 Properties properties = readOrCreateProperties( directory, PROJECT_METADATA_KEY ); 986 987 ProjectMetadata project = null; 988 989 String id = properties.getProperty( "id" ); 990 if ( id != null ) 991 { 992 project = new ProjectMetadata(); 993 project.setNamespace( properties.getProperty( "namespace" ) ); 994 project.setId( id ); 995 } 996 997 return project; 998 } 999 catch ( IOException e ) 1000 { 1001 throw new MetadataResolutionException( e.getMessage(), e ); 1002 } 1003 } 1004 1005 @Override 1006 public ProjectVersionMetadata getProjectVersion( String repoId, String namespace, String projectId, 1007 String projectVersion ) 1008 throws MetadataResolutionException 1009 { 1010 try 1011 { 1012 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion ); 1013 1014 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 1015 String id = properties.getProperty( "id" ); 1016 ProjectVersionMetadata versionMetadata = null; 1017 if ( id != null ) 1018 { 1019 versionMetadata = new ProjectVersionMetadata(); 1020 versionMetadata.setId( id ); 1021 versionMetadata.setName( properties.getProperty( "name" ) ); 1022 versionMetadata.setDescription( properties.getProperty( "description" ) ); 1023 versionMetadata.setUrl( properties.getProperty( "url" ) ); 1024 versionMetadata.setIncomplete( Boolean.valueOf( properties.getProperty( "incomplete", "false" ) ) ); 1025 1026 String scmConnection = properties.getProperty( "scm.connection" ); 1027 String scmDeveloperConnection = properties.getProperty( "scm.developerConnection" ); 1028 String scmUrl = properties.getProperty( "scm.url" ); 1029 if ( scmConnection != null || scmDeveloperConnection != null || scmUrl != null ) 1030 { 1031 Scm scm = new Scm(); 1032 scm.setConnection( scmConnection ); 1033 scm.setDeveloperConnection( scmDeveloperConnection ); 1034 scm.setUrl( scmUrl ); 1035 versionMetadata.setScm( scm ); 1036 } 1037 1038 String ciSystem = properties.getProperty( "ci.system" ); 1039 String ciUrl = properties.getProperty( "ci.url" ); 1040 if ( ciSystem != null || ciUrl != null ) 1041 { 1042 CiManagement ci = new CiManagement(); 1043 ci.setSystem( ciSystem ); 1044 ci.setUrl( ciUrl ); 1045 versionMetadata.setCiManagement( ci ); 1046 } 1047 1048 String issueSystem = properties.getProperty( "issue.system" ); 1049 String issueUrl = properties.getProperty( "issue.url" ); 1050 if ( issueSystem != null || issueUrl != null ) 1051 { 1052 IssueManagement issueManagement = new IssueManagement(); 1053 issueManagement.setSystem( issueSystem ); 1054 issueManagement.setUrl( issueUrl ); 1055 versionMetadata.setIssueManagement( issueManagement ); 1056 } 1057 1058 String orgName = properties.getProperty( "org.name" ); 1059 String orgUrl = properties.getProperty( "org.url" ); 1060 if ( orgName != null || orgUrl != null ) 1061 { 1062 Organization org = new Organization(); 1063 org.setName( orgName ); 1064 org.setUrl( orgUrl ); 1065 versionMetadata.setOrganization( org ); 1066 } 1067 1068 boolean done = false; 1069 int i = 0; 1070 while ( !done ) 1071 { 1072 String licenseName = properties.getProperty( "license." + i + ".name" ); 1073 String licenseUrl = properties.getProperty( "license." + i + ".url" ); 1074 if ( licenseName != null || licenseUrl != null ) 1075 { 1076 License license = new License(); 1077 license.setName( licenseName ); 1078 license.setUrl( licenseUrl ); 1079 versionMetadata.addLicense( license ); 1080 } 1081 else 1082 { 1083 done = true; 1084 } 1085 i++; 1086 } 1087 1088 done = false; 1089 i = 0; 1090 while ( !done ) 1091 { 1092 String mailingListName = properties.getProperty( "mailingList." + i + ".name" ); 1093 if ( mailingListName != null ) 1094 { 1095 MailingList mailingList = new MailingList(); 1096 mailingList.setName( mailingListName ); 1097 mailingList.setMainArchiveUrl( properties.getProperty( "mailingList." + i + ".archive" ) ); 1098 String p = properties.getProperty( "mailingList." + i + ".otherArchives" ); 1099 if ( p != null && p.length() > 0 ) 1100 { 1101 mailingList.setOtherArchives( Arrays.asList( p.split( "," ) ) ); 1102 } 1103 else 1104 { 1105 mailingList.setOtherArchives( Collections.<String>emptyList() ); 1106 } 1107 mailingList.setPostAddress( properties.getProperty( "mailingList." + i + ".post" ) ); 1108 mailingList.setSubscribeAddress( properties.getProperty( "mailingList." + i + ".subscribe" ) ); 1109 mailingList.setUnsubscribeAddress( 1110 properties.getProperty( "mailingList." + i + ".unsubscribe" ) ); 1111 versionMetadata.addMailingList( mailingList ); 1112 } 1113 else 1114 { 1115 done = true; 1116 } 1117 i++; 1118 } 1119 1120 done = false; 1121 i = 0; 1122 while ( !done ) 1123 { 1124 String dependencyArtifactId = properties.getProperty( "dependency." + i + ".artifactId" ); 1125 if ( dependencyArtifactId != null ) 1126 { 1127 Dependency dependency = new Dependency(); 1128 dependency.setArtifactId( dependencyArtifactId ); 1129 dependency.setGroupId( properties.getProperty( "dependency." + i + ".groupId" ) ); 1130 dependency.setClassifier( properties.getProperty( "dependency." + i + ".classifier" ) ); 1131 dependency.setOptional( 1132 Boolean.valueOf( properties.getProperty( "dependency." + i + ".optional" ) ) ); 1133 dependency.setScope( properties.getProperty( "dependency." + i + ".scope" ) ); 1134 dependency.setSystemPath( properties.getProperty( "dependency." + i + ".systemPath" ) ); 1135 dependency.setType( properties.getProperty( "dependency." + i + ".type" ) ); 1136 dependency.setVersion( properties.getProperty( "dependency." + i + ".version" ) ); 1137 dependency.setOptional( 1138 Boolean.valueOf( properties.getProperty( "dependency." + i + ".optional" ) ) ); 1139 versionMetadata.addDependency( dependency ); 1140 } 1141 else 1142 { 1143 done = true; 1144 } 1145 i++; 1146 } 1147 1148 String facetIds = properties.getProperty( "facetIds", "" ); 1149 if ( facetIds.length() > 0 ) 1150 { 1151 for ( String facetId : facetIds.split( "," ) ) 1152 { 1153 MetadataFacetFactory factory = metadataFacetFactories.get( facetId ); 1154 if ( factory == null ) 1155 { 1156 log.error( "Attempted to load unknown project version metadata facet: {}", facetId ); 1157 } 1158 else 1159 { 1160 MetadataFacet facet = factory.createMetadataFacet(); 1161 Map<String, String> map = new HashMap<>(); 1162 for ( Object key : new ArrayList( properties.keySet() ) ) 1163 { 1164 String property = (String) key; 1165 if ( property.startsWith( facet.getFacetId() ) ) 1166 { 1167 map.put( property.substring( facet.getFacetId().length() + 1 ), 1168 properties.getProperty( property ) ); 1169 } 1170 } 1171 facet.fromProperties( map ); 1172 versionMetadata.addFacet( facet ); 1173 } 1174 } 1175 } 1176 1177 updateProjectVersionFacets( versionMetadata, properties ); 1178 } 1179 return versionMetadata; 1180 } 1181 catch ( IOException e ) 1182 { 1183 throw new MetadataResolutionException( e.getMessage(), e ); 1184 } 1185 } 1186 1187 @Override 1188 public Collection<String> getArtifactVersions( String repoId, String namespace, String projectId, 1189 String projectVersion ) 1190 throws MetadataResolutionException 1191 { 1192 try 1193 { 1194 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion ); 1195 1196 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 1197 1198 Set<String> versions = new HashSet<String>(); 1199 for ( Map.Entry entry : properties.entrySet() ) 1200 { 1201 String name = (String) entry.getKey(); 1202 if ( name.startsWith( "artifact:version:" ) ) 1203 { 1204 versions.add( (String) entry.getValue() ); 1205 } 1206 } 1207 return versions; 1208 } 1209 catch ( IOException e ) 1210 { 1211 throw new MetadataResolutionException( e.getMessage(), e ); 1212 } 1213 } 1214 1215 @Override 1216 public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId, 1217 String projectVersion ) 1218 throws MetadataResolutionException 1219 { 1220 try 1221 { 1222 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion ); 1223 1224 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY ); 1225 int numberOfRefs = Integer.parseInt( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1; 1226 1227 List<ProjectVersionReference> references = new ArrayList<>(); 1228 for ( int i = 0; i < numberOfRefs; i++ ) 1229 { 1230 ProjectVersionReference reference = new ProjectVersionReference(); 1231 reference.setProjectId( properties.getProperty( "ref:reference." + i + ".projectId" ) ); 1232 reference.setNamespace( properties.getProperty( "ref:reference." + i + ".namespace" ) ); 1233 reference.setProjectVersion( properties.getProperty( "ref:reference." + i + ".projectVersion" ) ); 1234 reference.setReferenceType( ProjectVersionReference.ReferenceType.valueOf( 1235 properties.getProperty( "ref:reference." + i + ".referenceType" ) ) ); 1236 references.add( reference ); 1237 } 1238 return references; 1239 } 1240 catch ( IOException e ) 1241 { 1242 throw new MetadataResolutionException( e.getMessage(), e ); 1243 } 1244 } 1245 1246 @Override 1247 public Collection<String> getRootNamespaces( String repoId ) 1248 throws MetadataResolutionException 1249 { 1250 return getNamespaces( repoId, null ); 1251 } 1252 1253 @Override 1254 public Collection<String> getNamespaces( String repoId, String baseNamespace ) 1255 throws MetadataResolutionException 1256 { 1257 try 1258 { 1259 List<String> allNamespaces = new ArrayList<>(); 1260 File directory = getDirectory( repoId ); 1261 File[] files = directory.listFiles(); 1262 if ( files != null ) 1263 { 1264 for ( File namespace : files ) 1265 { 1266 if ( new File( namespace, NAMESPACE_METADATA_KEY + ".properties" ).exists() ) 1267 { 1268 allNamespaces.add( namespace.getName() ); 1269 } 1270 } 1271 } 1272 1273 Set<String> namespaces = new LinkedHashSet<>(); 1274 int fromIndex = baseNamespace != null ? baseNamespace.length() + 1 : 0; 1275 for ( String namespace : allNamespaces ) 1276 { 1277 if ( baseNamespace == null || namespace.startsWith( baseNamespace + "." ) ) 1278 { 1279 int i = namespace.indexOf( '.', fromIndex ); 1280 if ( i >= 0 ) 1281 { 1282 namespaces.add( namespace.substring( fromIndex, i ) ); 1283 } 1284 else 1285 { 1286 namespaces.add( namespace.substring( fromIndex ) ); 1287 } 1288 } 1289 } 1290 return new ArrayList<>( namespaces ); 1291 } 1292 catch ( IOException e ) 1293 { 1294 throw new MetadataResolutionException( e.getMessage(), e ); 1295 } 1296 } 1297 1298 @Override 1299 public Collection<String> getProjects( String repoId, String namespace ) 1300 throws MetadataResolutionException 1301 { 1302 try 1303 { 1304 List<String> projects = new ArrayList<>(); 1305 File directory = new File( getDirectory( repoId ), namespace ); 1306 File[] files = directory.listFiles(); 1307 if ( files != null ) 1308 { 1309 for ( File project : files ) 1310 { 1311 if ( new File( project, PROJECT_METADATA_KEY + ".properties" ).exists() ) 1312 { 1313 projects.add( project.getName() ); 1314 } 1315 } 1316 } 1317 return projects; 1318 } 1319 catch ( IOException e ) 1320 { 1321 throw new MetadataResolutionException( e.getMessage(), e ); 1322 } 1323 } 1324 1325 @Override 1326 public Collection<String> getProjectVersions( String repoId, String namespace, String projectId ) 1327 throws MetadataResolutionException 1328 { 1329 try 1330 { 1331 List<String> projectVersions = new ArrayList<>(); 1332 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId ); 1333 File[] files = directory.listFiles(); 1334 if ( files != null ) 1335 { 1336 for ( File projectVersion : files ) 1337 { 1338 if ( new File( projectVersion, PROJECT_VERSION_METADATA_KEY + ".properties" ).exists() ) 1339 { 1340 projectVersions.add( projectVersion.getName() ); 1341 } 1342 } 1343 } 1344 return projectVersions; 1345 } 1346 catch ( IOException e ) 1347 { 1348 throw new MetadataResolutionException( e.getMessage(), e ); 1349 } 1350 } 1351 1352 @Override 1353 public void removeProject( String repositoryId, String namespace, String projectId ) 1354 throws MetadataRepositoryException 1355 { 1356 try 1357 { 1358 File directory = new File( getDirectory( repositoryId ), namespace + "/" + projectId ); 1359 FileUtils.deleteDirectory( directory ); 1360 } 1361 catch ( IOException e ) 1362 { 1363 throw new MetadataRepositoryException( e.getMessage(), e ); 1364 } 1365 } 1366 1367 @Override 1368 public void removeProjectVersion( String repoId, String namespace, String projectId, String projectVersion ) 1369 throws MetadataRepositoryException 1370 { 1371 try 1372 { 1373 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion ); 1374 FileUtils.deleteDirectory( directory ); 1375 } 1376 catch ( IOException e ) 1377 { 1378 throw new MetadataRepositoryException( e.getMessage(), e ); 1379 } 1380 1381 } 1382 1383 private void writeProperties( Properties properties, File directory, String propertiesKey ) 1384 throws IOException 1385 { 1386 directory.mkdirs(); 1387 try (OutputStream os = Files.newOutputStream( new File( directory, propertiesKey + ".properties" ).toPath() )) 1388 { 1389 properties.store( os, null ); 1390 } 1391 } 1392 1393 private static class ArtifactComparator 1394 implements Comparator<ArtifactMetadata> 1395 { 1396 @Override 1397 public int compare( ArtifactMetadata artifact1, ArtifactMetadata artifact2 ) 1398 { 1399 if ( artifact1.getWhenGathered() == artifact2.getWhenGathered() ) 1400 { 1401 return 0; 1402 } 1403 if ( artifact1.getWhenGathered() == null ) 1404 { 1405 return 1; 1406 } 1407 if ( artifact2.getWhenGathered() == null ) 1408 { 1409 return -1; 1410 } 1411 return artifact1.getWhenGathered().compareTo( artifact2.getWhenGathered() ); 1412 } 1413 } 1414 1415 @Override 1416 public List<ArtifactMetadata> getArtifacts( String repoId ) 1417 throws MetadataRepositoryException 1418 { 1419 try 1420 { 1421 List<ArtifactMetadata> artifacts = new ArrayList<>(); 1422 for ( String ns : getRootNamespaces( repoId ) ) 1423 { 1424 getArtifacts( artifacts, repoId, ns ); 1425 } 1426 return artifacts; 1427 } 1428 catch ( MetadataResolutionException e ) 1429 { 1430 throw new MetadataRepositoryException( e.getMessage(), e ); 1431 } 1432 } 1433 1434 private void getArtifacts( List<ArtifactMetadata> artifacts, String repoId, String ns ) 1435 throws MetadataResolutionException 1436 { 1437 for ( String namespace : getNamespaces( repoId, ns ) ) 1438 { 1439 getArtifacts( artifacts, repoId, ns + "." + namespace ); 1440 } 1441 1442 for ( String project : getProjects( repoId, ns ) ) 1443 { 1444 for ( String version : getProjectVersions( repoId, ns, project ) ) 1445 { 1446 for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) ) 1447 { 1448 artifacts.add( artifact ); 1449 } 1450 } 1451 } 1452 } 1453 1454 @Override 1455 public List<ArtifactMetadata> searchArtifacts( String text, String repositoryId, boolean exact ) 1456 throws MetadataRepositoryException 1457 { 1458 throw new UnsupportedOperationException( "searchArtifacts not yet implemented in File backend" ); 1459 } 1460 1461 @Override 1462 public List<ArtifactMetadata> searchArtifacts( String key, String text, String repositoryId, boolean exact ) 1463 throws MetadataRepositoryException 1464 { 1465 throw new UnsupportedOperationException( "searchArtifacts not yet implemented in File backend" ); 1466 } 1467}