1 package org.apache.archiva.metadata.repository.file;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.archiva.metadata.model.ArtifactMetadata;
23 import org.apache.archiva.metadata.model.CiManagement;
24 import org.apache.archiva.metadata.model.Dependency;
25 import org.apache.archiva.metadata.model.IssueManagement;
26 import org.apache.archiva.metadata.model.License;
27 import org.apache.archiva.metadata.model.MailingList;
28 import org.apache.archiva.metadata.model.MetadataFacet;
29 import org.apache.archiva.metadata.model.MetadataFacetFactory;
30 import org.apache.archiva.metadata.model.Organization;
31 import org.apache.archiva.metadata.model.ProjectMetadata;
32 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
33 import org.apache.archiva.metadata.model.ProjectVersionReference;
34 import org.apache.archiva.metadata.model.Scm;
35 import org.apache.archiva.metadata.repository.MetadataRepository;
36 import org.apache.commons.io.FileUtils;
37 import org.apache.commons.io.IOUtils;
38 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerFactory;
43 import java.io.FileInputStream;
44 import java.io.FileNotFoundException;
45 import java.io.FileOutputStream;
46 import java.io.IOException;
47 import java.util.ArrayList;
48 import java.util.Arrays;
49 import java.util.Collection;
50 import java.util.Collections;
51 import java.util.Comparator;
52 import java.util.Date;
53 import java.util.HashMap;
54 import java.util.HashSet;
55 import java.util.LinkedHashSet;
56 import java.util.List;
58 import java.util.Properties;
60 import java.util.StringTokenizer;
63 * @plexus.component role="org.apache.archiva.metadata.repository.MetadataRepository"
65 public class FileMetadataRepository
66 implements MetadataRepository
69 * @plexus.requirement role="org.apache.archiva.metadata.model.MetadataFacetFactory"
71 private Map<String, MetadataFacetFactory> metadataFacetFactories;
76 private ArchivaConfiguration configuration;
78 private static final Logger log = LoggerFactory.getLogger( FileMetadataRepository.class );
80 private static final String PROJECT_METADATA_KEY = "project-metadata";
82 private static final String PROJECT_VERSION_METADATA_KEY = "version-metadata";
84 private static final String NAMESPACE_METADATA_KEY = "namespace-metadata";
86 private static final String METADATA_KEY = "metadata";
88 private File getBaseDirectory( String repoId )
90 // TODO: should be configurable, like the index
91 String basedir = configuration.getConfiguration().getManagedRepositoriesAsMap().get( repoId ).getLocation();
92 File dir = new File( basedir, ".archiva" );
96 private File getDirectory( String repoId )
98 return new File( getBaseDirectory( repoId ), "content" );
101 public void updateProject( String repoId, ProjectMetadata project )
103 updateProject( repoId, project.getNamespace(), project.getId() );
106 private void updateProject( String repoId, String namespace, String id )
108 // TODO: this is a more braindead implementation than we would normally expect, for prototyping purposes
109 updateNamespace( repoId, namespace );
113 File namespaceDirectory = new File( getDirectory( repoId ), namespace );
114 Properties properties = new Properties();
115 properties.setProperty( "namespace", namespace );
116 properties.setProperty( "id", id );
117 writeProperties( properties, new File( namespaceDirectory, id ), PROJECT_METADATA_KEY );
119 catch ( IOException e )
126 public void updateProjectVersion( String repoId, String namespace, String projectId,
127 ProjectVersionMetadata versionMetadata )
129 updateProject( repoId, namespace, projectId );
131 File directory = new File( getDirectory( repoId ),
132 namespace + "/" + projectId + "/" + versionMetadata.getId() );
134 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
135 // remove properties that are not references or artifacts
136 for ( Object key : new ArrayList( properties.keySet() ) )
138 String name = (String) key;
139 if ( !name.contains( ":" ) && !name.equals( "facetIds" ) )
141 properties.remove( name );
144 properties.setProperty( "id", versionMetadata.getId() );
145 setProperty( properties, "name", versionMetadata.getName() );
146 setProperty( properties, "description", versionMetadata.getDescription() );
147 setProperty( properties, "url", versionMetadata.getUrl() );
148 setProperty( properties, "incomplete", String.valueOf( versionMetadata.isIncomplete() ) );
149 if ( versionMetadata.getScm() != null )
151 setProperty( properties, "scm.connection", versionMetadata.getScm().getConnection() );
152 setProperty( properties, "scm.developerConnection", versionMetadata.getScm().getDeveloperConnection() );
153 setProperty( properties, "scm.url", versionMetadata.getScm().getUrl() );
155 if ( versionMetadata.getCiManagement() != null )
157 setProperty( properties, "ci.system", versionMetadata.getCiManagement().getSystem() );
158 setProperty( properties, "ci.url", versionMetadata.getCiManagement().getUrl() );
160 if ( versionMetadata.getIssueManagement() != null )
162 setProperty( properties, "issue.system", versionMetadata.getIssueManagement().getSystem() );
163 setProperty( properties, "issue.url", versionMetadata.getIssueManagement().getUrl() );
165 if ( versionMetadata.getOrganization() != null )
167 setProperty( properties, "org.name", versionMetadata.getOrganization().getName() );
168 setProperty( properties, "org.url", versionMetadata.getOrganization().getUrl() );
171 for ( License license : versionMetadata.getLicenses() )
173 setProperty( properties, "license." + i + ".name", license.getName() );
174 setProperty( properties, "license." + i + ".url", license.getUrl() );
178 for ( MailingList mailingList : versionMetadata.getMailingLists() )
180 setProperty( properties, "mailingList." + i + ".archive", mailingList.getMainArchiveUrl() );
181 setProperty( properties, "mailingList." + i + ".name", mailingList.getName() );
182 setProperty( properties, "mailingList." + i + ".post", mailingList.getPostAddress() );
183 setProperty( properties, "mailingList." + i + ".unsubscribe", mailingList.getUnsubscribeAddress() );
184 setProperty( properties, "mailingList." + i + ".subscribe", mailingList.getSubscribeAddress() );
185 setProperty( properties, "mailingList." + i + ".otherArchives", join( mailingList.getOtherArchives() ) );
189 for ( Dependency dependency : versionMetadata.getDependencies() )
191 setProperty( properties, "dependency." + i + ".classifier", dependency.getClassifier() );
192 setProperty( properties, "dependency." + i + ".scope", dependency.getScope() );
193 setProperty( properties, "dependency." + i + ".systemPath", dependency.getSystemPath() );
194 setProperty( properties, "dependency." + i + ".artifactId", dependency.getArtifactId() );
195 setProperty( properties, "dependency." + i + ".groupId", dependency.getGroupId() );
196 setProperty( properties, "dependency." + i + ".version", dependency.getVersion() );
197 setProperty( properties, "dependency." + i + ".type", dependency.getType() );
200 Set<String> facetIds = new LinkedHashSet<String>( versionMetadata.getFacetIds() );
201 facetIds.addAll( Arrays.asList( properties.getProperty( "facetIds", "" ).split( "," ) ) );
202 properties.setProperty( "facetIds", join( facetIds ) );
204 updateProjectVersionFacets( versionMetadata, properties );
208 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
210 catch ( IOException e )
213 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
217 private void updateProjectVersionFacets( ProjectVersionMetadata versionMetadata, Properties properties )
219 for ( MetadataFacet facet : versionMetadata.getFacetList() )
221 for ( Map.Entry<String,String> entry : facet.toProperties().entrySet() )
223 properties.setProperty( facet.getFacetId() + ":" + entry.getKey(), entry.getValue() );
228 public void updateProjectReference( String repoId, String namespace, String projectId, String projectVersion,
229 ProjectVersionReference reference )
231 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
233 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
234 int i = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
235 setProperty( properties, "ref:lastReferenceNum", Integer.toString( i ) );
236 setProperty( properties, "ref:reference." + i + ".namespace", reference.getNamespace() );
237 setProperty( properties, "ref:reference." + i + ".projectId", reference.getProjectId() );
238 setProperty( properties, "ref:reference." + i + ".projectVersion", reference.getProjectVersion() );
239 setProperty( properties, "ref:reference." + i + ".referenceType", reference.getReferenceType().toString() );
243 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
245 catch ( IOException e )
248 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
252 public void updateNamespace( String repoId, String namespace )
256 File namespaceDirectory = new File( getDirectory( repoId ), namespace );
257 Properties properties = new Properties();
258 properties.setProperty( "namespace", namespace );
259 writeProperties( properties, namespaceDirectory, NAMESPACE_METADATA_KEY );
262 catch ( IOException e )
269 public List<String> getMetadataFacets( String repoId, String facetId )
271 File directory = getMetadataDirectory( repoId, facetId );
272 List<String> facets = new ArrayList<String>();
273 recurse( facets, "", directory );
277 private void recurse( List<String> facets, String prefix, File directory )
279 File[] list = directory.listFiles();
282 for ( File dir : list )
284 if ( dir.isDirectory() )
286 recurse( facets, prefix + "/" + dir.getName(), dir );
288 else if ( dir.getName().equals( METADATA_KEY + ".properties" ) )
290 facets.add( prefix.substring( 1 ) );
296 public MetadataFacet getMetadataFacet( String repositoryId, String facetId, String name )
298 Properties properties;
301 properties = readProperties( new File( getMetadataDirectory( repositoryId, facetId ), name ),
304 catch ( FileNotFoundException e )
308 catch ( IOException e )
311 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
314 MetadataFacet metadataFacet = null;
315 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
316 if ( metadataFacetFactory != null )
318 metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
319 Map<String, String> map = new HashMap<String, String>();
320 for ( Object key : new ArrayList( properties.keySet() ) )
322 String property = (String) key;
323 map.put( property, properties.getProperty( property ) );
325 metadataFacet.fromProperties( map );
327 return metadataFacet;
330 public void addMetadataFacet( String repositoryId, MetadataFacet metadataFacet )
332 Properties properties = new Properties();
333 properties.putAll( metadataFacet.toProperties() );
337 File directory = new File( getMetadataDirectory( repositoryId, metadataFacet.getFacetId() ),
338 metadataFacet.getName() );
339 writeProperties( properties, directory, METADATA_KEY );
341 catch ( IOException e )
344 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
348 public void removeMetadataFacets( String repositoryId, String facetId )
352 FileUtils.deleteDirectory( getMetadataDirectory( repositoryId, facetId ) );
354 catch ( IOException e )
357 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
361 public void removeMetadataFacet( String repoId, String facetId, String name )
363 File dir = new File( getMetadataDirectory( repoId, facetId ), name );
366 FileUtils.deleteDirectory( dir );
368 catch ( IOException e )
371 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
375 public List<ArtifactMetadata> getArtifactsByDateRange( String repoId, Date startTime, Date endTime )
377 // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
378 // of this information (eg. in Lucene, as before)
380 List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
381 for ( String ns : getRootNamespaces( repoId ) )
383 getArtifactsByDateRange( artifacts, repoId, ns, startTime, endTime );
385 Collections.sort( artifacts, new ArtifactComparator() );
389 private void getArtifactsByDateRange( List<ArtifactMetadata> artifacts, String repoId, String ns, Date startTime,
392 for ( String namespace : getNamespaces( repoId, ns ) )
394 getArtifactsByDateRange( artifacts, repoId, ns + "." + namespace, startTime, endTime );
397 for ( String project : getProjects( repoId, ns ) )
399 for ( String version : getProjectVersions( repoId, ns, project ) )
401 for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) )
403 if ( startTime == null || startTime.before( artifact.getWhenGathered() ) )
405 if ( endTime == null || endTime.after( artifact.getWhenGathered() ) )
407 artifacts.add( artifact );
415 public Collection<ArtifactMetadata> getArtifacts( String repoId, String namespace, String projectId,
416 String projectVersion )
418 Map<String, ArtifactMetadata> artifacts = new HashMap<String, ArtifactMetadata>();
420 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
422 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
424 for ( Map.Entry entry : properties.entrySet() )
426 String name = (String) entry.getKey();
427 StringTokenizer tok = new StringTokenizer( name, ":" );
428 if ( tok.hasMoreTokens() && "artifact".equals( tok.nextToken() ) )
430 String field = tok.nextToken();
431 String id = tok.nextToken();
433 ArtifactMetadata artifact = artifacts.get( id );
434 if ( artifact == null )
436 artifact = new ArtifactMetadata();
437 artifact.setRepositoryId( repoId );
438 artifact.setNamespace( namespace );
439 artifact.setProject( projectId );
440 artifact.setProjectVersion( projectVersion );
441 artifact.setVersion( projectVersion );
442 artifact.setId( id );
443 artifacts.put( id, artifact );
446 String value = (String) entry.getValue();
447 if ( "updated".equals( field ) )
449 artifact.setFileLastModified( Long.valueOf( value ) );
451 else if ( "size".equals( field ) )
453 artifact.setSize( Long.valueOf( value ) );
455 else if ( "whenGathered".equals( field ) )
457 artifact.setWhenGathered( new Date( Long.valueOf( value ) ) );
459 else if ( "version".equals( field ) )
461 artifact.setVersion( value );
463 else if ( "md5".equals( field ) )
465 artifact.setMd5( value );
467 else if ( "sha1".equals( field ) )
469 artifact.setSha1( value );
471 else if ( "facetIds".equals( field ) )
473 if ( value.length() > 0 )
475 String propertyPrefix = "artifact:facet:" + id + ":";
476 for ( String facetId : value.split( "," ) )
478 MetadataFacetFactory factory = metadataFacetFactories.get( facetId );
479 if ( factory == null )
481 log.error( "Attempted to load unknown artifact metadata facet: " + facetId );
485 MetadataFacet facet = factory.createMetadataFacet();
486 String prefix = propertyPrefix + facet.getFacetId();
487 Map<String, String> map = new HashMap<String, String>();
488 for ( Object key : new ArrayList( properties.keySet() ) )
490 String property = (String) key;
491 if ( property.startsWith( prefix ) )
493 map.put( property.substring( prefix.length() + 1 ), properties.getProperty(
497 facet.fromProperties( map );
498 artifact.addFacet( facet );
503 updateArtifactFacets( artifact, properties );
507 return artifacts.values();
510 private void updateArtifactFacets( ArtifactMetadata artifact, Properties properties )
512 String propertyPrefix = "artifact:facet:" + artifact.getId() + ":";
513 for ( MetadataFacet facet : artifact.getFacetList() )
515 for ( Map.Entry<String, String> e : facet.toProperties().entrySet() )
517 String key = propertyPrefix + facet.getFacetId() + ":" + e.getKey();
518 properties.setProperty( key, e.getValue() );
523 public Collection<String> getRepositories()
525 return configuration.getConfiguration().getManagedRepositoriesAsMap().keySet();
528 public List<ArtifactMetadata> getArtifactsByChecksum( String repositoryId, String checksum )
530 // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
531 // of this information (eg. in Lucene, as before)
532 // alternatively, we could build a referential tree in the content repository, however it would need some levels
533 // of depth to avoid being too broad to be useful (eg. /repository/checksums/a/ab/abcdef1234567)
535 List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
536 for ( String ns : getRootNamespaces( repositoryId ) )
538 getArtifactsByChecksum( artifacts, repositoryId, ns, checksum );
543 public void deleteArtifact( String repoId, String namespace, String project, String version, String id )
545 File directory = new File( getDirectory( repoId ), namespace + "/" + project + "/" + version );
547 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
549 properties.remove( "artifact:updated:" + id );
550 properties.remove( "artifact:whenGathered:" + id );
551 properties.remove( "artifact:size:" + id );
552 properties.remove( "artifact:md5:" + id );
553 properties.remove( "artifact:sha1:" + id );
554 properties.remove( "artifact:version:" + id );
555 properties.remove( "artifact:facetIds:" + id );
557 String prefix = "artifact:facet:" + id + ":";
558 for ( Object key : new ArrayList( properties.keySet() ) )
560 String property = (String) key;
561 if ( property.startsWith( prefix ) )
563 properties.remove( property );
569 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
571 catch ( IOException e )
574 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
578 public void deleteRepository( String repoId )
582 FileUtils.deleteDirectory( getDirectory( repoId ) );
584 catch ( IOException e )
587 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
591 private void getArtifactsByChecksum( List<ArtifactMetadata> artifacts, String repositoryId, String ns,
594 for ( String namespace : getNamespaces( repositoryId, ns ) )
596 getArtifactsByChecksum( artifacts, repositoryId, ns + "." + namespace, checksum );
599 for ( String project : getProjects( repositoryId, ns ) )
601 for ( String version : getProjectVersions( repositoryId, ns, project ) )
603 for ( ArtifactMetadata artifact : getArtifacts( repositoryId, ns, project, version ) )
605 if ( checksum.equals( artifact.getMd5() ) || checksum.equals( artifact.getSha1() ) )
607 artifacts.add( artifact );
614 private File getMetadataDirectory( String repoId, String facetId )
616 return new File( getBaseDirectory( repoId ), "facets/" + facetId );
619 private String join( Collection<String> ids )
621 if ( ids != null && !ids.isEmpty() )
623 StringBuilder s = new StringBuilder();
624 for ( String id : ids )
629 return s.substring( 0, s.length() - 1 );
634 private void setProperty( Properties properties, String name, String value )
638 properties.setProperty( name, value );
642 public void updateArtifact( String repoId, String namespace, String projectId, String projectVersion,
643 ArtifactMetadata artifact )
645 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
647 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
649 String id = artifact.getId();
650 properties.setProperty( "artifact:updated:" + id, Long.toString( artifact.getFileLastModified().getTime() ) );
651 properties.setProperty( "artifact:whenGathered:" + id, Long.toString( artifact.getWhenGathered().getTime() ) );
652 properties.setProperty( "artifact:size:" + id, Long.toString( artifact.getSize() ) );
653 if ( artifact.getMd5() != null )
655 properties.setProperty( "artifact:md5:" + id, artifact.getMd5() );
657 if ( artifact.getSha1() != null )
659 properties.setProperty( "artifact:sha1:" + id, artifact.getSha1() );
661 properties.setProperty( "artifact:version:" + id, artifact.getVersion() );
663 Set<String> facetIds = new LinkedHashSet<String>( artifact.getFacetIds() );
664 String property = "artifact:facetIds:" + id;
665 facetIds.addAll( Arrays.asList( properties.getProperty( property, "" ).split( "," ) ) );
666 properties.setProperty( property, join( facetIds ) );
668 updateArtifactFacets( artifact, properties );
672 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
674 catch ( IOException e )
677 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
681 private Properties readOrCreateProperties( File directory, String propertiesKey )
685 return readProperties( directory, propertiesKey );
687 catch ( FileNotFoundException e )
689 // ignore and return new properties
691 catch ( IOException e )
694 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
696 return new Properties();
699 private Properties readProperties( File directory, String propertiesKey )
702 Properties properties = new Properties();
703 FileInputStream in = null;
706 in = new FileInputStream( new File( directory, propertiesKey + ".properties" ) );
707 properties.load( in );
711 IOUtils.closeQuietly( in );
716 public ProjectMetadata getProject( String repoId, String namespace, String projectId )
718 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId );
720 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
722 ProjectMetadata project = new ProjectMetadata();
723 project.setNamespace( properties.getProperty( "namespace" ) );
724 project.setId( properties.getProperty( "id" ) );
728 public ProjectVersionMetadata getProjectVersion( String repoId, String namespace, String projectId,
729 String projectVersion )
731 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
733 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
734 String id = properties.getProperty( "id" );
735 ProjectVersionMetadata versionMetadata = null;
738 versionMetadata = new ProjectVersionMetadata();
739 versionMetadata.setId( id );
740 versionMetadata.setName( properties.getProperty( "name" ) );
741 versionMetadata.setDescription( properties.getProperty( "description" ) );
742 versionMetadata.setUrl( properties.getProperty( "url" ) );
743 versionMetadata.setIncomplete( Boolean.valueOf( properties.getProperty( "incomplete", "false" ) ) );
745 String scmConnection = properties.getProperty( "scm.connection" );
746 String scmDeveloperConnection = properties.getProperty( "scm.developerConnection" );
747 String scmUrl = properties.getProperty( "scm.url" );
748 if ( scmConnection != null || scmDeveloperConnection != null || scmUrl != null )
751 scm.setConnection( scmConnection );
752 scm.setDeveloperConnection( scmDeveloperConnection );
753 scm.setUrl( scmUrl );
754 versionMetadata.setScm( scm );
757 String ciSystem = properties.getProperty( "ci.system" );
758 String ciUrl = properties.getProperty( "ci.url" );
759 if ( ciSystem != null || ciUrl != null )
761 CiManagement ci = new CiManagement();
762 ci.setSystem( ciSystem );
764 versionMetadata.setCiManagement( ci );
767 String issueSystem = properties.getProperty( "issue.system" );
768 String issueUrl = properties.getProperty( "issue.url" );
769 if ( issueSystem != null || issueUrl != null )
771 IssueManagement issueManagement = new IssueManagement();
772 issueManagement.setSystem( issueSystem );
773 issueManagement.setUrl( issueUrl );
774 versionMetadata.setIssueManagement( issueManagement );
777 String orgName = properties.getProperty( "org.name" );
778 String orgUrl = properties.getProperty( "org.url" );
779 if ( orgName != null || orgUrl != null )
781 Organization org = new Organization();
782 org.setName( orgName );
783 org.setUrl( orgUrl );
784 versionMetadata.setOrganization( org );
787 boolean done = false;
791 String licenseName = properties.getProperty( "license." + i + ".name" );
792 String licenseUrl = properties.getProperty( "license." + i + ".url" );
793 if ( licenseName != null || licenseUrl != null )
795 License license = new License();
796 license.setName( licenseName );
797 license.setUrl( licenseUrl );
798 versionMetadata.addLicense( license );
811 String mailingListName = properties.getProperty( "mailingList." + i + ".name" );
812 if ( mailingListName != null )
814 MailingList mailingList = new MailingList();
815 mailingList.setName( mailingListName );
816 mailingList.setMainArchiveUrl( properties.getProperty( "mailingList." + i + ".archive" ) );
817 mailingList.setOtherArchives( Arrays.asList( properties.getProperty(
818 "mailingList." + i + ".otherArchives" ).split( "," ) ) );
819 mailingList.setPostAddress( properties.getProperty( "mailingList." + i + ".post" ) );
820 mailingList.setSubscribeAddress( properties.getProperty( "mailingList." + i + ".subscribe" ) );
821 mailingList.setUnsubscribeAddress( properties.getProperty( "mailingList." + i + ".unsubscribe" ) );
822 versionMetadata.addMailingList( mailingList );
835 String dependencyArtifactId = properties.getProperty( "dependency." + i + ".artifactId" );
836 if ( dependencyArtifactId != null )
838 Dependency dependency = new Dependency();
839 dependency.setArtifactId( dependencyArtifactId );
840 dependency.setGroupId( properties.getProperty( "dependency." + i + ".groupId" ) );
841 dependency.setClassifier( properties.getProperty( "dependency." + i + ".classifier" ) );
842 dependency.setOptional( Boolean.valueOf( properties.getProperty(
843 "dependency." + i + ".optional" ) ) );
844 dependency.setScope( properties.getProperty( "dependency." + i + ".scope" ) );
845 dependency.setSystemPath( properties.getProperty( "dependency." + i + ".systemPath" ) );
846 dependency.setType( properties.getProperty( "dependency." + i + ".type" ) );
847 dependency.setVersion( properties.getProperty( "dependency." + i + ".version" ) );
848 versionMetadata.addDependency( dependency );
857 String facetIds = properties.getProperty( "facetIds", "" );
858 if ( facetIds.length() > 0 )
860 for ( String facetId : facetIds.split( "," ) )
862 MetadataFacetFactory factory = metadataFacetFactories.get( facetId );
863 if ( factory == null )
865 log.error( "Attempted to load unknown project version metadata facet: " + facetId );
869 MetadataFacet facet = factory.createMetadataFacet();
870 Map<String, String> map = new HashMap<String, String>();
871 for ( Object key : new ArrayList( properties.keySet() ) )
873 String property = (String) key;
874 if ( property.startsWith( facet.getFacetId() ) )
876 map.put( property.substring( facet.getFacetId().length() + 1 ), properties.getProperty(
880 facet.fromProperties( map );
881 versionMetadata.addFacet( facet );
886 updateProjectVersionFacets( versionMetadata, properties );
888 return versionMetadata;
891 public Collection<String> getArtifactVersions( String repoId, String namespace, String projectId,
892 String projectVersion )
894 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
896 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
898 Set<String> versions = new HashSet<String>();
899 for ( Map.Entry entry : properties.entrySet() )
901 String name = (String) entry.getKey();
902 if ( name.startsWith( "artifact:version:" ) )
904 versions.add( (String) entry.getValue() );
910 public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId,
911 String projectVersion )
913 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
915 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
916 int numberOfRefs = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
918 List<ProjectVersionReference> references = new ArrayList<ProjectVersionReference>();
919 for ( int i = 0; i < numberOfRefs; i++ )
921 ProjectVersionReference reference = new ProjectVersionReference();
922 reference.setProjectId( properties.getProperty( "ref:reference." + i + ".projectId" ) );
923 reference.setNamespace( properties.getProperty( "ref:reference." + i + ".namespace" ) );
924 reference.setProjectVersion( properties.getProperty( "ref:reference." + i + ".projectVersion" ) );
925 reference.setReferenceType( ProjectVersionReference.ReferenceType.valueOf( properties.getProperty(
926 "ref:reference." + i + ".referenceType" ) ) );
927 references.add( reference );
932 public Collection<String> getRootNamespaces( String repoId )
934 return getNamespaces( repoId, null );
937 public Collection<String> getNamespaces( String repoId, String baseNamespace )
939 List<String> allNamespaces = new ArrayList<String>();
940 File directory = getDirectory( repoId );
941 File[] files = directory.listFiles();
944 for ( File namespace : files )
946 if ( new File( namespace, NAMESPACE_METADATA_KEY + ".properties" ).exists() )
948 allNamespaces.add( namespace.getName() );
953 Set<String> namespaces = new LinkedHashSet<String>();
954 int fromIndex = baseNamespace != null ? baseNamespace.length() + 1 : 0;
955 for ( String namespace : allNamespaces )
957 if ( baseNamespace == null || namespace.startsWith( baseNamespace + "." ) )
959 int i = namespace.indexOf( '.', fromIndex );
962 namespaces.add( namespace.substring( fromIndex, i ) );
966 namespaces.add( namespace.substring( fromIndex ) );
970 return new ArrayList<String>( namespaces );
973 public Collection<String> getProjects( String repoId, String namespace )
975 List<String> projects = new ArrayList<String>();
976 File directory = new File( getDirectory( repoId ), namespace );
977 File[] files = directory.listFiles();
980 for ( File project : files )
982 if ( new File( project, PROJECT_METADATA_KEY + ".properties" ).exists() )
984 projects.add( project.getName() );
991 public Collection<String> getProjectVersions( String repoId, String namespace, String projectId )
993 List<String> projectVersions = new ArrayList<String>();
994 File directory = new File( getDirectory( repoId ), namespace + "/" + projectId );
995 File[] files = directory.listFiles();
998 for ( File projectVersion : files )
1000 if ( new File( projectVersion, PROJECT_VERSION_METADATA_KEY + ".properties" ).exists() )
1002 projectVersions.add( projectVersion.getName() );
1006 return projectVersions;
1009 private void writeProperties( Properties properties, File directory, String propertiesKey )
1013 FileOutputStream os = new FileOutputStream( new File( directory, propertiesKey + ".properties" ) );
1016 properties.store( os, null );
1020 IOUtils.closeQuietly( os );
1024 public void setMetadataFacetFactories( Map<String, MetadataFacetFactory> metadataFacetFactories )
1026 this.metadataFacetFactories = metadataFacetFactories;
1029 public void setConfiguration( ArchivaConfiguration configuration )
1031 this.configuration = configuration;
1034 private static class ArtifactComparator
1035 implements Comparator<ArtifactMetadata>
1037 public int compare( ArtifactMetadata artifact1, ArtifactMetadata artifact2 )
1039 if ( artifact1.getWhenGathered() == artifact2.getWhenGathered() )
1043 if ( artifact1.getWhenGathered() == null )
1047 if ( artifact2.getWhenGathered() == null )
1051 return artifact1.getWhenGathered().compareTo( artifact2.getWhenGathered() );