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
23 import java.io.FileInputStream;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Date;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.LinkedHashSet;
35 import java.util.List;
37 import java.util.Properties;
39 import java.util.StringTokenizer;
41 import org.apache.archiva.metadata.model.ArtifactMetadata;
42 import org.apache.archiva.metadata.model.CiManagement;
43 import org.apache.archiva.metadata.model.Dependency;
44 import org.apache.archiva.metadata.model.IssueManagement;
45 import org.apache.archiva.metadata.model.License;
46 import org.apache.archiva.metadata.model.MailingList;
47 import org.apache.archiva.metadata.model.MetadataFacet;
48 import org.apache.archiva.metadata.model.MetadataFacetFactory;
49 import org.apache.archiva.metadata.model.Organization;
50 import org.apache.archiva.metadata.model.ProjectMetadata;
51 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
52 import org.apache.archiva.metadata.model.ProjectVersionReference;
53 import org.apache.archiva.metadata.model.Scm;
54 import org.apache.archiva.metadata.repository.MetadataRepository;
55 import org.apache.commons.io.FileUtils;
56 import org.apache.commons.io.IOUtils;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
61 * @plexus.component role="org.apache.archiva.metadata.repository.MetadataRepository"
63 public class FileMetadataRepository
64 implements MetadataRepository
67 * TODO: this isn't suitable for production use
69 * @plexus.configuration
71 private File directory = new File( System.getProperty( "user.home" ), ".archiva-metadata" );
74 * @plexus.requirement role="org.apache.archiva.metadata.model.MetadataFacetFactory"
76 private Map<String, MetadataFacetFactory> metadataFacetFactories;
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 public void updateProject( String repoId, ProjectMetadata project )
90 updateProject( repoId, project.getNamespace(), project.getId() );
93 private void updateProject( String repoId, String namespace, String id )
95 // TODO: this is a more braindead implementation than we would normally expect, for prototyping purposes
96 updateNamespace( repoId, namespace );
100 File namespaceDirectory = new File( this.directory, repoId + "/" + namespace );
101 Properties properties = new Properties();
102 properties.setProperty( "namespace", namespace );
103 properties.setProperty( "id", id );
104 writeProperties( properties, new File( namespaceDirectory, id ), PROJECT_METADATA_KEY );
106 catch ( IOException e )
113 public void updateProjectVersion( String repoId, String namespace, String projectId,
114 ProjectVersionMetadata versionMetadata )
116 updateProject( repoId, namespace, projectId );
119 new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + versionMetadata.getId() );
121 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
122 // remove properties that are not references or artifacts
123 for ( Object key : properties.keySet() )
125 String name = (String) key;
126 if ( !name.contains( ":" ) && !name.equals( "facetIds" ) )
128 properties.remove( name );
131 properties.setProperty( "id", versionMetadata.getId() );
132 setProperty( properties, "name", versionMetadata.getName() );
133 setProperty( properties, "description", versionMetadata.getDescription() );
134 setProperty( properties, "url", versionMetadata.getUrl() );
135 setProperty( properties, "incomplete", String.valueOf( versionMetadata.isIncomplete() ) );
136 if ( versionMetadata.getScm() != null )
138 setProperty( properties, "scm.connection", versionMetadata.getScm().getConnection() );
139 setProperty( properties, "scm.developerConnection", versionMetadata.getScm().getDeveloperConnection() );
140 setProperty( properties, "scm.url", versionMetadata.getScm().getUrl() );
142 if ( versionMetadata.getCiManagement() != null )
144 setProperty( properties, "ci.system", versionMetadata.getCiManagement().getSystem() );
145 setProperty( properties, "ci.url", versionMetadata.getCiManagement().getUrl() );
147 if ( versionMetadata.getIssueManagement() != null )
149 setProperty( properties, "issue.system", versionMetadata.getIssueManagement().getSystem() );
150 setProperty( properties, "issue.url", versionMetadata.getIssueManagement().getUrl() );
152 if ( versionMetadata.getOrganization() != null )
154 setProperty( properties, "org.name", versionMetadata.getOrganization().getName() );
155 setProperty( properties, "org.url", versionMetadata.getOrganization().getUrl() );
158 for ( License license : versionMetadata.getLicenses() )
160 setProperty( properties, "license." + i + ".name", license.getName() );
161 setProperty( properties, "license." + i + ".url", license.getUrl() );
165 for ( MailingList mailingList : versionMetadata.getMailingLists() )
167 setProperty( properties, "mailingList." + i + ".archive", mailingList.getMainArchiveUrl() );
168 setProperty( properties, "mailingList." + i + ".name", mailingList.getName() );
169 setProperty( properties, "mailingList." + i + ".post", mailingList.getPostAddress() );
170 setProperty( properties, "mailingList." + i + ".unsubscribe", mailingList.getUnsubscribeAddress() );
171 setProperty( properties, "mailingList." + i + ".subscribe", mailingList.getSubscribeAddress() );
172 setProperty( properties, "mailingList." + i + ".otherArchives", join( mailingList.getOtherArchives() ) );
176 for ( Dependency dependency : versionMetadata.getDependencies() )
178 setProperty( properties, "dependency." + i + ".classifier", dependency.getClassifier() );
179 setProperty( properties, "dependency." + i + ".scope", dependency.getScope() );
180 setProperty( properties, "dependency." + i + ".systemPath", dependency.getSystemPath() );
181 setProperty( properties, "dependency." + i + ".artifactId", dependency.getArtifactId() );
182 setProperty( properties, "dependency." + i + ".groupId", dependency.getGroupId() );
183 setProperty( properties, "dependency." + i + ".version", dependency.getVersion() );
184 setProperty( properties, "dependency." + i + ".type", dependency.getType() );
187 Set<String> facetIds = new LinkedHashSet<String>( versionMetadata.getFacetIds() );
188 facetIds.addAll( Arrays.asList( properties.getProperty( "facetIds", "" ).split( "," ) ) );
189 properties.setProperty( "facetIds", join( facetIds ) );
191 for ( MetadataFacet facet : versionMetadata.getFacetList() )
193 properties.putAll( facet.toProperties() );
198 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
200 catch ( IOException e )
203 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
207 public void updateProjectReference( String repoId, String namespace, String projectId, String projectVersion,
208 ProjectVersionReference reference )
210 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
212 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
213 int i = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
214 setProperty( properties, "ref:lastReferenceNum", Integer.toString( i ) );
215 setProperty( properties, "ref:reference." + i + ".namespace", reference.getNamespace() );
216 setProperty( properties, "ref:reference." + i + ".projectId", reference.getProjectId() );
217 setProperty( properties, "ref:reference." + i + ".projectVersion", reference.getProjectVersion() );
218 setProperty( properties, "ref:reference." + i + ".referenceType", reference.getReferenceType().toString() );
222 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
224 catch ( IOException e )
227 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
231 public void updateNamespace( String repoId, String namespace )
235 File namespaceDirectory = new File( this.directory, repoId + "/" + namespace );
236 Properties properties = new Properties();
237 properties.setProperty( "namespace", namespace );
238 writeProperties( properties, namespaceDirectory, NAMESPACE_METADATA_KEY );
241 catch ( IOException e )
248 public List<String> getMetadataFacets( String repoId, String facetId )
250 File directory = getMetadataDirectory( repoId, facetId );
251 List<String> facets = new ArrayList<String>();
252 recurse( facets, "", directory );
256 private void recurse( List<String> facets, String prefix, File directory )
258 File[] list = directory.listFiles();
261 for ( File dir : list )
263 if ( dir.isDirectory() )
265 recurse( facets, prefix + "/" + dir.getName(), dir );
267 else if ( dir.getName().equals( METADATA_KEY + ".properties" ) )
269 facets.add( prefix.substring( 1 ) );
275 public MetadataFacet getMetadataFacet( String repositoryId, String facetId, String name )
277 Properties properties;
281 readProperties( new File( getMetadataDirectory( repositoryId, facetId ), name ), METADATA_KEY );
283 catch ( FileNotFoundException e )
287 catch ( IOException e )
290 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
293 MetadataFacet metadataFacet = null;
294 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
295 if ( metadataFacetFactory != null )
297 metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
298 Map<String, String> map = new HashMap<String, String>();
299 for ( Object key : properties.keySet() )
301 String property = (String) key;
302 map.put( property, properties.getProperty( property ) );
304 metadataFacet.fromProperties( map );
306 return metadataFacet;
309 public void addMetadataFacet( String repositoryId, MetadataFacet metadataFacet )
311 Properties properties = new Properties();
312 properties.putAll( metadataFacet.toProperties() );
317 new File( getMetadataDirectory( repositoryId, metadataFacet.getFacetId() ), metadataFacet.getName() );
318 writeProperties( properties, directory, METADATA_KEY );
320 catch ( IOException e )
323 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
327 public void removeMetadataFacets( String repositoryId, String facetId )
331 FileUtils.deleteDirectory( getMetadataDirectory( repositoryId, facetId ) );
333 catch ( IOException e )
336 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
340 public void removeMetadataFacet( String repoId, String facetId, String name )
342 File dir = new File( getMetadataDirectory( repoId, facetId ), name );
345 FileUtils.deleteDirectory( dir );
347 catch ( IOException e )
350 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
354 public List<ArtifactMetadata> getArtifactsByDateRange( String repoId, Date startTime, Date endTime )
356 // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
357 // of this information (eg. in Lucene, as before)
359 List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
360 for ( String ns : getRootNamespaces( repoId ) )
362 getArtifactsByDateRange( artifacts, repoId, ns, startTime, endTime );
367 private void getArtifactsByDateRange( List<ArtifactMetadata> artifacts, String repoId, String ns, Date startTime,
370 for ( String namespace : getNamespaces( repoId, ns ) )
372 getArtifactsByDateRange( artifacts, repoId, ns + "." + namespace, startTime, endTime );
375 for ( String project : getProjects( repoId, ns ) )
377 for ( String version : getProjectVersions( repoId, ns, project ) )
379 for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) )
381 if ( startTime == null || startTime.before( artifact.getWhenGathered() ) )
383 if ( endTime == null || endTime.after( artifact.getWhenGathered() ) )
385 artifacts.add( artifact );
393 public Collection<ArtifactMetadata> getArtifacts( String repoId, String namespace, String projectId,
394 String projectVersion )
396 Map<String, ArtifactMetadata> artifacts = new HashMap<String, ArtifactMetadata>();
398 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
400 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
402 for ( Map.Entry entry : properties.entrySet() )
404 String name = (String) entry.getKey();
405 StringTokenizer tok = new StringTokenizer( name, ":" );
406 if ( tok.hasMoreTokens() && "artifact".equals( tok.nextToken() ) )
408 String field = tok.nextToken();
409 String id = tok.nextToken();
411 ArtifactMetadata artifact = artifacts.get( id );
412 if ( artifact == null )
414 artifact = new ArtifactMetadata();
415 artifact.setRepositoryId( repoId );
416 artifact.setNamespace( namespace );
417 artifact.setProject( projectId );
418 artifact.setVersion( projectVersion );
419 artifact.setId( id );
420 artifacts.put( id, artifact );
423 String value = (String) entry.getValue();
424 if ( "updated".equals( field ) )
426 artifact.setFileLastModified( Long.valueOf( value ) );
428 else if ( "size".equals( field ) )
430 artifact.setSize( Long.valueOf( value ) );
432 else if ( "whenGathered".equals( field ) )
434 artifact.setWhenGathered( new Date( Long.valueOf( value ) ) );
436 else if ( "version".equals( field ) )
438 artifact.setVersion( value );
440 else if ( "md5".equals( field ) )
442 artifact.setMd5( value );
444 else if ( "sha1".equals( field ) )
446 artifact.setSha1( value );
450 return artifacts.values();
453 public Collection<String> getRepositories()
455 String[] repoIds = this.directory.list();
456 return repoIds != null ? Arrays.asList( repoIds ) : Collections.<String>emptyList();
459 public List<ArtifactMetadata> getArtifactsByChecksum( String repositoryId, String checksum )
461 // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
462 // of this information (eg. in Lucene, as before)
463 // alternatively, we could build a referential tree in the content repository, however it would need some levels
464 // of depth to avoid being too broad to be useful (eg. /repository/checksums/a/ab/abcdef1234567)
466 List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
467 for ( String ns : getRootNamespaces( repositoryId ) )
469 getArtifactsByChecksum( artifacts, repositoryId, ns, checksum );
474 public void deleteArtifact( String repositoryId, String namespace, String project, String version, String id )
476 File directory = new File( this.directory, repositoryId + "/" + namespace + "/" + project + "/" + version );
478 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
480 properties.remove( "artifact:updated:" + id );
481 properties.remove( "artifact:whenGathered:" + id );
482 properties.remove( "artifact:size:" + id );
483 properties.remove( "artifact:md5:" + id );
484 properties.remove( "artifact:sha1:" + id );
485 properties.remove( "artifact:version:" + id );
489 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
491 catch ( IOException e )
494 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
498 public void deleteRepository( String repoId )
500 File directory = new File( this.directory, repoId );
504 FileUtils.deleteDirectory( directory );
506 catch ( IOException e )
509 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
513 private void getArtifactsByChecksum( List<ArtifactMetadata> artifacts, String repositoryId, String ns,
516 for ( String namespace : getNamespaces( repositoryId, ns ) )
518 getArtifactsByChecksum( artifacts, repositoryId, ns + "." + namespace, checksum );
521 for ( String project : getProjects( repositoryId, ns ) )
523 for ( String version : getProjectVersions( repositoryId, ns, project ) )
525 for ( ArtifactMetadata artifact : getArtifacts( repositoryId, ns, project, version ) )
527 if ( checksum.equals( artifact.getMd5() ) || checksum.equals( artifact.getSha1() ) )
529 artifacts.add( artifact );
536 private File getMetadataDirectory( String repositoryId, String facetId )
538 return new File( this.directory, repositoryId + "/.meta/" + facetId );
541 private String join( Collection<String> ids )
543 if ( !ids.isEmpty() )
545 StringBuilder s = new StringBuilder();
546 for ( String id : ids )
551 return s.substring( 0, s.length() - 1 );
556 private void setProperty( Properties properties, String name, String value )
560 properties.setProperty( name, value );
564 public void updateArtifact( String repoId, String namespace, String projectId, String projectVersion,
565 ArtifactMetadata artifact )
567 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
569 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
571 properties.setProperty( "artifact:updated:" + artifact.getId(),
572 Long.toString( artifact.getFileLastModified().getTime() ) );
573 properties.setProperty( "artifact:whenGathered:" + artifact.getId(),
574 Long.toString( artifact.getWhenGathered().getTime() ) );
575 properties.setProperty( "artifact:size:" + artifact.getId(), Long.toString( artifact.getSize() ) );
576 if ( artifact.getMd5() != null )
578 properties.setProperty( "artifact:md5:" + artifact.getId(), artifact.getMd5() );
580 if ( artifact.getSha1() != null )
582 properties.setProperty( "artifact:sha1:" + artifact.getId(), artifact.getSha1() );
584 properties.setProperty( "artifact:version:" + artifact.getId(), artifact.getVersion() );
588 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
590 catch ( IOException e )
593 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
597 private Properties readOrCreateProperties( File directory, String propertiesKey )
601 return readProperties( directory, propertiesKey );
603 catch ( FileNotFoundException e )
605 // ignore and return new properties
607 catch ( IOException e )
610 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
612 return new Properties();
615 private Properties readProperties( File directory, String propertiesKey )
618 Properties properties = new Properties();
619 FileInputStream in = null;
622 in = new FileInputStream( new File( directory, propertiesKey + ".properties" ) );
623 properties.load( in );
627 IOUtils.closeQuietly( in );
632 public ProjectMetadata getProject( String repoId, String namespace, String projectId )
634 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId );
636 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
638 ProjectMetadata project = new ProjectMetadata();
639 project.setNamespace( properties.getProperty( "namespace" ) );
640 project.setId( properties.getProperty( "id" ) );
644 public ProjectVersionMetadata getProjectVersion( String repoId, String namespace, String projectId,
645 String projectVersion )
647 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
649 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
650 String id = properties.getProperty( "id" );
651 ProjectVersionMetadata versionMetadata = null;
654 versionMetadata = new ProjectVersionMetadata();
655 versionMetadata.setId( id );
656 versionMetadata.setName( properties.getProperty( "name" ) );
657 versionMetadata.setDescription( properties.getProperty( "description" ) );
658 versionMetadata.setUrl( properties.getProperty( "url" ) );
659 versionMetadata.setIncomplete( Boolean.valueOf( properties.getProperty( "incomplete", "false" ) ) );
661 String scmConnection = properties.getProperty( "scm.connection" );
662 String scmDeveloperConnection = properties.getProperty( "scm.developerConnection" );
663 String scmUrl = properties.getProperty( "scm.url" );
664 if ( scmConnection != null || scmDeveloperConnection != null || scmUrl != null )
667 scm.setConnection( scmConnection );
668 scm.setDeveloperConnection( scmDeveloperConnection );
669 scm.setUrl( scmUrl );
670 versionMetadata.setScm( scm );
673 String ciSystem = properties.getProperty( "ci.system" );
674 String ciUrl = properties.getProperty( "ci.url" );
675 if ( ciSystem != null || ciUrl != null )
677 CiManagement ci = new CiManagement();
678 ci.setSystem( ciSystem );
680 versionMetadata.setCiManagement( ci );
683 String issueSystem = properties.getProperty( "issue.system" );
684 String issueUrl = properties.getProperty( "issue.url" );
685 if ( issueSystem != null || issueUrl != null )
687 IssueManagement issueManagement = new IssueManagement();
688 issueManagement.setSystem( issueSystem );
689 issueManagement.setUrl( issueUrl );
690 versionMetadata.setIssueManagement( issueManagement );
693 String orgName = properties.getProperty( "org.name" );
694 String orgUrl = properties.getProperty( "org.url" );
695 if ( orgName != null || orgUrl != null )
697 Organization org = new Organization();
698 org.setName( orgName );
699 org.setUrl( orgUrl );
700 versionMetadata.setOrganization( org );
703 boolean done = false;
707 String licenseName = properties.getProperty( "license." + i + ".name" );
708 String licenseUrl = properties.getProperty( "license." + i + ".url" );
709 if ( licenseName != null || licenseUrl != null )
711 License license = new License();
712 license.setName( licenseName );
713 license.setUrl( licenseUrl );
714 versionMetadata.addLicense( license );
727 String mailingListName = properties.getProperty( "mailingList." + i + ".name" );
728 if ( mailingListName != null )
730 MailingList mailingList = new MailingList();
731 mailingList.setName( mailingListName );
732 mailingList.setMainArchiveUrl( properties.getProperty( "mailingList." + i + ".archive" ) );
733 mailingList.setOtherArchives(
734 Arrays.asList( properties.getProperty( "mailingList." + i + ".otherArchives" ).split( "," ) ) );
735 mailingList.setPostAddress( properties.getProperty( "mailingList." + i + ".post" ) );
736 mailingList.setSubscribeAddress( properties.getProperty( "mailingList." + i + ".subscribe" ) );
737 mailingList.setUnsubscribeAddress( properties.getProperty( "mailingList." + i + ".unsubscribe" ) );
738 versionMetadata.addMailingList( mailingList );
751 String dependencyArtifactId = properties.getProperty( "dependency." + i + ".artifactId" );
752 if ( dependencyArtifactId != null )
754 Dependency dependency = new Dependency();
755 dependency.setArtifactId( dependencyArtifactId );
756 dependency.setGroupId( properties.getProperty( "dependency." + i + ".groupId" ) );
757 dependency.setClassifier( properties.getProperty( "dependency." + i + ".classifier" ) );
758 dependency.setOptional(
759 Boolean.valueOf( properties.getProperty( "dependency." + i + ".optional" ) ) );
760 dependency.setScope( properties.getProperty( "dependency." + i + ".scope" ) );
761 dependency.setSystemPath( properties.getProperty( "dependency." + i + ".systemPath" ) );
762 dependency.setType( properties.getProperty( "dependency." + i + ".type" ) );
763 dependency.setVersion( properties.getProperty( "dependency." + i + ".version" ) );
764 versionMetadata.addDependency( dependency );
773 String facetIds = properties.getProperty( "facetIds", "" );
774 if ( facetIds.length() > 0 )
776 for ( String facetId : facetIds.split( "," ) )
778 MetadataFacetFactory factory = metadataFacetFactories.get( facetId );
779 if ( factory == null )
781 log.error( "Attempted to load unknown metadata facet: " + facetId );
785 MetadataFacet facet = factory.createMetadataFacet();
786 Map<String, String> map = new HashMap<String, String>();
787 for ( Object key : properties.keySet() )
789 String property = (String) key;
790 if ( property.startsWith( facet.getFacetId() ) )
792 map.put( property, properties.getProperty( property ) );
795 facet.fromProperties( map );
796 versionMetadata.addFacet( facet );
801 for ( MetadataFacet facet : versionMetadata.getFacetList() )
803 properties.putAll( facet.toProperties() );
806 return versionMetadata;
809 public Collection<String> getArtifactVersions( String repoId, String namespace, String projectId,
810 String projectVersion )
812 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
814 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
816 Set<String> versions = new HashSet<String>();
817 for ( Map.Entry entry : properties.entrySet() )
819 String name = (String) entry.getKey();
820 if ( name.startsWith( "artifact:version:" ) )
822 versions.add( (String) entry.getValue() );
828 public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId,
829 String projectVersion )
831 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
833 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
834 int numberOfRefs = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
836 List<ProjectVersionReference> references = new ArrayList<ProjectVersionReference>();
837 for ( int i = 0; i < numberOfRefs; i++ )
839 ProjectVersionReference reference = new ProjectVersionReference();
840 reference.setProjectId( properties.getProperty( "ref:reference." + i + ".projectId" ) );
841 reference.setNamespace( properties.getProperty( "ref:reference." + i + ".namespace" ) );
842 reference.setProjectVersion( properties.getProperty( "ref:reference." + i + ".projectVersion" ) );
843 reference.setReferenceType( ProjectVersionReference.ReferenceType.valueOf(
844 properties.getProperty( "ref:reference." + i + ".referenceType" ) ) );
845 references.add( reference );
850 public Collection<String> getRootNamespaces( String repoId )
852 return getNamespaces( repoId, null );
855 public Collection<String> getNamespaces( String repoId, String baseNamespace )
857 List<String> allNamespaces = new ArrayList<String>();
858 File directory = new File( this.directory, repoId );
859 File[] files = directory.listFiles();
862 for ( File namespace : files )
864 if ( new File( namespace, NAMESPACE_METADATA_KEY + ".properties" ).exists() )
866 allNamespaces.add( namespace.getName() );
871 Set<String> namespaces = new LinkedHashSet<String>();
872 int fromIndex = baseNamespace != null ? baseNamespace.length() + 1 : 0;
873 for ( String namespace : allNamespaces )
875 if ( baseNamespace == null || namespace.startsWith( baseNamespace + "." ) )
877 int i = namespace.indexOf( '.', fromIndex );
880 namespaces.add( namespace.substring( fromIndex, i ) );
884 namespaces.add( namespace.substring( fromIndex ) );
888 return new ArrayList<String>( namespaces );
891 public Collection<String> getProjects( String repoId, String namespace )
893 List<String> projects = new ArrayList<String>();
894 File directory = new File( this.directory, repoId + "/" + namespace );
895 File[] files = directory.listFiles();
898 for ( File project : files )
900 if ( new File( project, PROJECT_METADATA_KEY + ".properties" ).exists() )
902 projects.add( project.getName() );
909 public Collection<String> getProjectVersions( String repoId, String namespace, String projectId )
911 List<String> projectVersions = new ArrayList<String>();
912 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId );
913 File[] files = directory.listFiles();
916 for ( File projectVersion : files )
918 if ( new File( projectVersion, PROJECT_VERSION_METADATA_KEY + ".properties" ).exists() )
920 projectVersions.add( projectVersion.getName() );
924 return projectVersions;
927 private void writeProperties( Properties properties, File directory, String propertiesKey )
931 FileOutputStream os = new FileOutputStream( new File( directory, propertiesKey + ".properties" ) );
934 properties.store( os, null );
938 IOUtils.closeQuietly( os );
942 public void setDirectory( File directory )
944 this.directory = directory;
947 public void setMetadataFacetFactories( Map<String, MetadataFacetFactory> metadataFacetFactories )
949 this.metadataFacetFactories = metadataFacetFactories;