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.LinkedHashSet;
34 import java.util.List;
36 import java.util.Properties;
38 import java.util.StringTokenizer;
40 import org.apache.archiva.metadata.model.ArtifactMetadata;
41 import org.apache.archiva.metadata.model.CiManagement;
42 import org.apache.archiva.metadata.model.Dependency;
43 import org.apache.archiva.metadata.model.IssueManagement;
44 import org.apache.archiva.metadata.model.License;
45 import org.apache.archiva.metadata.model.MailingList;
46 import org.apache.archiva.metadata.model.MetadataFacet;
47 import org.apache.archiva.metadata.model.MetadataFacetFactory;
48 import org.apache.archiva.metadata.model.Organization;
49 import org.apache.archiva.metadata.model.ProjectMetadata;
50 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
51 import org.apache.archiva.metadata.model.ProjectVersionReference;
52 import org.apache.archiva.metadata.model.Scm;
53 import org.apache.archiva.metadata.repository.MetadataRepository;
54 import org.apache.commons.io.FileUtils;
55 import org.apache.commons.io.IOUtils;
56 import org.slf4j.Logger;
57 import org.slf4j.LoggerFactory;
60 * @plexus.component role="org.apache.archiva.metadata.repository.MetadataRepository"
62 public class FileMetadataRepository
63 implements MetadataRepository
66 * TODO: this isn't suitable for production use
68 * @plexus.configuration
70 private File directory = new File( System.getProperty( "user.home" ), ".archiva-metadata" );
73 * @plexus.requirement role="org.apache.archiva.metadata.model.MetadataFacetFactory"
75 private Map<String, MetadataFacetFactory> metadataFacetFactories;
77 private static final Logger log = LoggerFactory.getLogger( FileMetadataRepository.class );
79 private static final String PROJECT_METADATA_KEY = "project-metadata";
81 private static final String PROJECT_VERSION_METADATA_KEY = "version-metadata";
83 private static final String NAMESPACE_METADATA_KEY = "namespace-metadata";
85 private static final String METADATA_KEY = "metadata";
87 public void updateProject( String repoId, ProjectMetadata project )
89 updateProject( repoId, project.getNamespace(), project.getId() );
92 private void updateProject( String repoId, String namespace, String id )
94 // TODO: this is a more braindead implementation than we would normally expect, for prototyping purposes
95 updateNamespace( repoId, namespace );
99 File namespaceDirectory = new File( this.directory, repoId + "/" + namespace );
100 Properties properties = new Properties();
101 properties.setProperty( "namespace", namespace );
102 properties.setProperty( "id", id );
103 writeProperties( properties, new File( namespaceDirectory, id ), PROJECT_METADATA_KEY );
105 catch ( IOException e )
112 public void updateProjectVersion( String repoId, String namespace, String projectId,
113 ProjectVersionMetadata versionMetadata )
115 updateProject( repoId, namespace, projectId );
118 new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + versionMetadata.getId() );
120 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
121 // remove properties that are not references or artifacts
122 for ( String name : properties.stringPropertyNames() )
124 if ( !name.contains( ":" ) && !name.equals( "facetIds" ) )
126 properties.remove( name );
129 properties.setProperty( "id", versionMetadata.getId() );
130 setProperty( properties, "name", versionMetadata.getName() );
131 setProperty( properties, "description", versionMetadata.getDescription() );
132 setProperty( properties, "url", versionMetadata.getUrl() );
133 if ( versionMetadata.getScm() != null )
135 setProperty( properties, "scm.connection", versionMetadata.getScm().getConnection() );
136 setProperty( properties, "scm.developerConnection", versionMetadata.getScm().getDeveloperConnection() );
137 setProperty( properties, "scm.url", versionMetadata.getScm().getUrl() );
139 if ( versionMetadata.getCiManagement() != null )
141 setProperty( properties, "ci.system", versionMetadata.getCiManagement().getSystem() );
142 setProperty( properties, "ci.url", versionMetadata.getCiManagement().getUrl() );
144 if ( versionMetadata.getIssueManagement() != null )
146 setProperty( properties, "issue.system", versionMetadata.getIssueManagement().getSystem() );
147 setProperty( properties, "issue.url", versionMetadata.getIssueManagement().getUrl() );
149 if ( versionMetadata.getOrganization() != null )
151 setProperty( properties, "org.name", versionMetadata.getOrganization().getName() );
152 setProperty( properties, "org.url", versionMetadata.getOrganization().getUrl() );
155 for ( License license : versionMetadata.getLicenses() )
157 setProperty( properties, "license." + i + ".name", license.getName() );
158 setProperty( properties, "license." + i + ".url", license.getUrl() );
162 for ( MailingList mailingList : versionMetadata.getMailingLists() )
164 setProperty( properties, "mailingList." + i + ".archive", mailingList.getMainArchiveUrl() );
165 setProperty( properties, "mailingList." + i + ".name", mailingList.getName() );
166 setProperty( properties, "mailingList." + i + ".post", mailingList.getPostAddress() );
167 setProperty( properties, "mailingList." + i + ".unsubscribe", mailingList.getUnsubscribeAddress() );
168 setProperty( properties, "mailingList." + i + ".subscribe", mailingList.getSubscribeAddress() );
169 setProperty( properties, "mailingList." + i + ".otherArchives", join( mailingList.getOtherArchives() ) );
173 for ( Dependency dependency : versionMetadata.getDependencies() )
175 setProperty( properties, "dependency." + i + ".classifier", dependency.getClassifier() );
176 setProperty( properties, "dependency." + i + ".scope", dependency.getScope() );
177 setProperty( properties, "dependency." + i + ".systemPath", dependency.getSystemPath() );
178 setProperty( properties, "dependency." + i + ".artifactId", dependency.getArtifactId() );
179 setProperty( properties, "dependency." + i + ".groupId", dependency.getGroupId() );
180 setProperty( properties, "dependency." + i + ".version", dependency.getVersion() );
181 setProperty( properties, "dependency." + i + ".type", dependency.getType() );
184 Set<String> facetIds = new LinkedHashSet<String>( versionMetadata.getFacetIds() );
185 facetIds.addAll( Arrays.asList( properties.getProperty( "facetIds", "" ).split( "," ) ) );
186 properties.setProperty( "facetIds", join( facetIds ) );
188 for ( MetadataFacet facet : versionMetadata.getFacetList() )
190 properties.putAll( facet.toProperties() );
195 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
197 catch ( IOException e )
200 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
204 public void updateProjectReference( String repoId, String namespace, String projectId, String projectVersion,
205 ProjectVersionReference reference )
207 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
209 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
210 int i = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
211 setProperty( properties, "ref:lastReferenceNum", Integer.toString( i ) );
212 setProperty( properties, "ref:reference." + i + ".namespace", reference.getNamespace() );
213 setProperty( properties, "ref:reference." + i + ".projectId", reference.getProjectId() );
214 setProperty( properties, "ref:reference." + i + ".projectVersion", reference.getProjectVersion() );
215 setProperty( properties, "ref:reference." + i + ".referenceType", reference.getReferenceType().toString() );
219 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
221 catch ( IOException e )
224 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
228 public void updateNamespace( String repoId, String namespace )
232 File namespaceDirectory = new File( this.directory, repoId + "/" + namespace );
233 Properties properties = new Properties();
234 properties.setProperty( "namespace", namespace );
235 writeProperties( properties, namespaceDirectory, NAMESPACE_METADATA_KEY );
238 catch ( IOException e )
245 public List<String> getMetadataFacets( String repoId, String facetId )
247 File directory = getMetadataDirectory( repoId, facetId );
248 String[] list = directory.list();
249 return list != null ? Arrays.asList( list ) : Collections.<String>emptyList();
252 public MetadataFacet getMetadataFacet( String repositoryId, String facetId, String name )
254 Properties properties;
258 readProperties( new File( getMetadataDirectory( repositoryId, facetId ), name ), METADATA_KEY );
260 catch ( FileNotFoundException e )
264 catch ( IOException e )
267 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
270 MetadataFacet metadataFacet = null;
271 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
272 if ( metadataFacetFactory != null )
274 metadataFacet = metadataFacetFactory.createMetadataFacet();
275 Map<String, String> map = new HashMap<String, String>();
276 for ( String key : properties.stringPropertyNames() )
278 map.put( key, properties.getProperty( key ) );
280 metadataFacet.fromProperties( map );
282 return metadataFacet;
285 public void addMetadataFacet( String repositoryId, String facetId, String name, MetadataFacet metadataFacet )
287 Properties properties = new Properties();
288 properties.putAll( metadataFacet.toProperties() );
292 writeProperties( properties, new File( getMetadataDirectory( repositoryId, facetId ), name ),
295 catch ( IOException e )
298 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
302 public void removeMetadataFacets( String repositoryId, String facetId )
306 FileUtils.deleteDirectory( getMetadataDirectory( repositoryId, facetId ) );
308 catch ( IOException e )
311 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
315 public List<ArtifactMetadata> getArtifactsByDateRange( String repoId, Date startTime, Date endTime )
317 // TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
318 // of this information (eg. in Lucene, as before)
320 List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
321 for ( String ns : getRootNamespaces( repoId ) )
323 getArtifactsByDateRange( artifacts, repoId, ns, startTime, endTime );
328 private void getArtifactsByDateRange( List<ArtifactMetadata> artifacts, String repoId, String ns, Date startTime,
331 for ( String namespace : getNamespaces( repoId, ns ) )
333 getArtifactsByDateRange( artifacts, repoId, ns + "." + namespace, startTime, endTime );
336 for ( String project : getProjects( repoId, ns ) )
338 for ( String version : getProjectVersions( repoId, ns, project ) )
340 for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) )
342 if ( startTime == null || startTime.before( artifact.getWhenGathered() ) )
344 if ( endTime == null || endTime.after( artifact.getWhenGathered() ) )
346 artifacts.add( artifact );
354 public Collection<ArtifactMetadata> getArtifacts( String repoId, String namespace, String projectId,
355 String projectVersion )
357 Map<String, ArtifactMetadata> artifacts = new HashMap<String, ArtifactMetadata>();
359 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
361 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
363 for ( Map.Entry entry : properties.entrySet() )
365 String name = (String) entry.getKey();
366 StringTokenizer tok = new StringTokenizer( name, ":" );
367 if ( tok.hasMoreTokens() && "artifact".equals( tok.nextToken() ) )
369 String field = tok.nextToken();
370 String id = tok.nextToken();
372 ArtifactMetadata artifact = artifacts.get( id );
373 if ( artifact == null )
375 artifact = new ArtifactMetadata();
376 artifact.setRepositoryId( repoId );
377 artifact.setNamespace( namespace );
378 artifact.setProject( projectId );
379 artifact.setVersion( projectVersion );
380 artifact.setId( id );
381 artifacts.put( id, artifact );
384 String value = (String) entry.getValue();
385 if ( "updated".equals( field ) )
387 artifact.setFileLastModified( Long.valueOf( value ) );
389 else if ( "size".equals( field ) )
391 artifact.setSize( Long.valueOf( value ) );
393 else if ( "whenGathered".equals( field ) )
395 artifact.setWhenGathered( new Date( Long.valueOf( value ) ) );
397 else if ( "version".equals( field ) )
399 artifact.setVersion( value );
401 else if ( "md5".equals( field ) )
403 artifact.setMd5( value );
405 else if ( "sha1".equals( field ) )
407 artifact.setSha1( value );
411 return artifacts.values();
414 public Collection<String> getRepositories()
416 String[] repoIds = this.directory.list();
417 return repoIds != null ? Arrays.asList( repoIds ) : Collections.<String>emptyList();
420 private File getMetadataDirectory( String repositoryId, String facetId )
422 return new File( this.directory, repositoryId + "/.meta/" + facetId );
425 private String join( Collection<String> ids )
427 if ( !ids.isEmpty() )
429 StringBuilder s = new StringBuilder();
430 for ( String id : ids )
435 return s.substring( 0, s.length() - 1 );
440 private void setProperty( Properties properties, String name, String value )
444 properties.setProperty( name, value );
448 public void updateArtifact( String repoId, String namespace, String projectId, String projectVersion,
449 ArtifactMetadata artifact )
451 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
453 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
455 properties.setProperty( "artifact:updated:" + artifact.getId(),
456 Long.toString( artifact.getFileLastModified().getTime() ) );
457 properties.setProperty( "artifact:whenGathered:" + artifact.getId(),
458 Long.toString( artifact.getWhenGathered().getTime() ) );
459 properties.setProperty( "artifact:size:" + artifact.getId(), Long.toString( artifact.getSize() ) );
460 if ( artifact.getMd5() != null )
462 properties.setProperty( "artifact:md5:" + artifact.getId(), artifact.getMd5() );
464 if ( artifact.getSha1() != null )
466 properties.setProperty( "artifact:sha1:" + artifact.getId(), artifact.getSha1() );
468 properties.setProperty( "artifact:version:" + artifact.getId(), artifact.getVersion() );
472 writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
474 catch ( IOException e )
477 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
481 private Properties readOrCreateProperties( File directory, String propertiesKey )
485 return readProperties( directory, propertiesKey );
487 catch ( FileNotFoundException e )
489 // ignore and return new properties
491 catch ( IOException e )
494 e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
496 return new Properties();
499 private Properties readProperties( File directory, String propertiesKey )
502 Properties properties = new Properties();
503 FileInputStream in = null;
506 in = new FileInputStream( new File( directory, propertiesKey + ".properties" ) );
507 properties.load( in );
511 IOUtils.closeQuietly( in );
516 public ProjectMetadata getProject( String repoId, String namespace, String projectId )
518 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId );
520 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
522 ProjectMetadata project = new ProjectMetadata();
523 project.setNamespace( properties.getProperty( "namespace" ) );
524 project.setId( properties.getProperty( "id" ) );
528 public ProjectVersionMetadata getProjectVersion( String repoId, String namespace, String projectId,
529 String projectVersion )
531 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
533 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
534 String id = properties.getProperty( "id" );
535 ProjectVersionMetadata versionMetadata = null;
538 versionMetadata = new ProjectVersionMetadata();
539 versionMetadata.setId( id );
540 versionMetadata.setName( properties.getProperty( "name" ) );
541 versionMetadata.setDescription( properties.getProperty( "description" ) );
542 versionMetadata.setUrl( properties.getProperty( "url" ) );
544 String scmConnection = properties.getProperty( "scm.connection" );
545 String scmDeveloperConnection = properties.getProperty( "scm.developerConnection" );
546 String scmUrl = properties.getProperty( "scm.url" );
547 if ( scmConnection != null || scmDeveloperConnection != null || scmUrl != null )
550 scm.setConnection( scmConnection );
551 scm.setDeveloperConnection( scmDeveloperConnection );
552 scm.setUrl( scmUrl );
553 versionMetadata.setScm( scm );
556 String ciSystem = properties.getProperty( "ci.system" );
557 String ciUrl = properties.getProperty( "ci.url" );
558 if ( ciSystem != null || ciUrl != null )
560 CiManagement ci = new CiManagement();
561 ci.setSystem( ciSystem );
563 versionMetadata.setCiManagement( ci );
566 String issueSystem = properties.getProperty( "issue.system" );
567 String issueUrl = properties.getProperty( "issue.url" );
568 if ( issueSystem != null || issueUrl != null )
570 IssueManagement issueManagement = new IssueManagement();
571 issueManagement.setSystem( issueSystem );
572 issueManagement.setUrl( issueUrl );
573 versionMetadata.setIssueManagement( issueManagement );
576 String orgName = properties.getProperty( "org.name" );
577 String orgUrl = properties.getProperty( "org.url" );
578 if ( orgName != null || orgUrl != null )
580 Organization org = new Organization();
581 org.setName( orgName );
582 org.setUrl( orgUrl );
583 versionMetadata.setOrganization( org );
586 boolean done = false;
590 String licenseName = properties.getProperty( "license." + i + ".name" );
591 String licenseUrl = properties.getProperty( "license." + i + ".url" );
592 if ( licenseName != null || licenseUrl != null )
594 License license = new License();
595 license.setName( licenseName );
596 license.setUrl( licenseUrl );
597 versionMetadata.addLicense( license );
610 String mailingListName = properties.getProperty( "mailingList." + i + ".name" );
611 if ( mailingListName != null )
613 MailingList mailingList = new MailingList();
614 mailingList.setName( mailingListName );
615 mailingList.setMainArchiveUrl( properties.getProperty( "mailingList." + i + ".archive" ) );
616 mailingList.setOtherArchives(
617 Arrays.asList( properties.getProperty( "mailingList." + i + ".otherArchives" ).split( "," ) ) );
618 mailingList.setPostAddress( properties.getProperty( "mailingList." + i + ".post" ) );
619 mailingList.setSubscribeAddress( properties.getProperty( "mailingList." + i + ".subscribe" ) );
620 mailingList.setUnsubscribeAddress( properties.getProperty( "mailingList." + i + ".unsubscribe" ) );
621 versionMetadata.addMailingList( mailingList );
634 String dependencyArtifactId = properties.getProperty( "dependency." + i + ".artifactId" );
635 if ( dependencyArtifactId != null )
637 Dependency dependency = new Dependency();
638 dependency.setArtifactId( dependencyArtifactId );
639 dependency.setGroupId( properties.getProperty( "dependency." + i + ".groupId" ) );
640 dependency.setClassifier( properties.getProperty( "dependency." + i + ".classifier" ) );
641 dependency.setOptional(
642 Boolean.valueOf( properties.getProperty( "dependency." + i + ".optional" ) ) );
643 dependency.setScope( properties.getProperty( "dependency." + i + ".scope" ) );
644 dependency.setSystemPath( properties.getProperty( "dependency." + i + ".systemPath" ) );
645 dependency.setType( properties.getProperty( "dependency." + i + ".type" ) );
646 dependency.setVersion( properties.getProperty( "dependency." + i + ".version" ) );
647 versionMetadata.addDependency( dependency );
656 for ( String facetId : properties.getProperty( "facetIds" ).split( "," ) )
658 MetadataFacetFactory factory = metadataFacetFactories.get( facetId );
659 if ( factory == null )
661 log.error( "Attempted to load unknown metadata facet: " + facetId );
665 MetadataFacet facet = factory.createMetadataFacet();
666 Map<String, String> map = new HashMap<String, String>();
667 for ( String key : properties.stringPropertyNames() )
669 if ( key.startsWith( facet.getFacetId() ) )
671 map.put( key, properties.getProperty( key ) );
674 facet.fromProperties( map );
675 versionMetadata.addFacet( facet );
679 for ( MetadataFacet facet : versionMetadata.getFacetList() )
681 properties.putAll( facet.toProperties() );
684 return versionMetadata;
687 public Collection<String> getArtifactVersions( String repoId, String namespace, String projectId,
688 String projectVersion )
690 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
692 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
694 List<String> versions = new ArrayList<String>();
695 for ( Map.Entry entry : properties.entrySet() )
697 String name = (String) entry.getKey();
698 if ( name.startsWith( "artifact:version:" ) )
700 versions.add( (String) entry.getValue() );
706 public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId,
707 String projectVersion )
709 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId + "/" + projectVersion );
711 Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
712 int numberOfRefs = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
714 List<ProjectVersionReference> references = new ArrayList<ProjectVersionReference>();
715 for ( int i = 0; i < numberOfRefs; i++ )
717 ProjectVersionReference reference = new ProjectVersionReference();
718 reference.setProjectId( properties.getProperty( "ref:reference." + i + ".projectId" ) );
719 reference.setNamespace( properties.getProperty( "ref:reference." + i + ".namespace" ) );
720 reference.setProjectVersion( properties.getProperty( "ref:reference." + i + ".projectVersion" ) );
721 reference.setReferenceType( ProjectVersionReference.ReferenceType.valueOf(
722 properties.getProperty( "ref:reference." + i + ".referenceType" ) ) );
723 references.add( reference );
728 public Collection<String> getRootNamespaces( String repoId )
730 return getNamespaces( repoId, null );
733 public Collection<String> getNamespaces( String repoId, String baseNamespace )
735 List<String> allNamespaces = new ArrayList<String>();
736 File directory = new File( this.directory, repoId );
737 File[] files = directory.listFiles();
740 for ( File namespace : files )
742 if ( new File( namespace, NAMESPACE_METADATA_KEY + ".properties" ).exists() )
744 allNamespaces.add( namespace.getName() );
749 Set<String> namespaces = new LinkedHashSet<String>();
750 int fromIndex = baseNamespace != null ? baseNamespace.length() + 1 : 0;
751 for ( String namespace : allNamespaces )
753 if ( baseNamespace == null || namespace.startsWith( baseNamespace + "." ) )
755 int i = namespace.indexOf( '.', fromIndex );
758 namespaces.add( namespace.substring( fromIndex, i ) );
762 namespaces.add( namespace.substring( fromIndex ) );
766 return new ArrayList<String>( namespaces );
769 public Collection<String> getProjects( String repoId, String namespace )
771 List<String> projects = new ArrayList<String>();
772 File directory = new File( this.directory, repoId + "/" + namespace );
773 File[] files = directory.listFiles();
776 for ( File project : files )
778 if ( new File( project, PROJECT_METADATA_KEY + ".properties" ).exists() )
780 projects.add( project.getName() );
787 public Collection<String> getProjectVersions( String repoId, String namespace, String projectId )
789 List<String> projectVersions = new ArrayList<String>();
790 File directory = new File( this.directory, repoId + "/" + namespace + "/" + projectId );
791 File[] files = directory.listFiles();
794 for ( File projectVersion : files )
796 if ( new File( projectVersion, PROJECT_VERSION_METADATA_KEY + ".properties" ).exists() )
798 projectVersions.add( projectVersion.getName() );
802 return projectVersions;
805 private void writeProperties( Properties properties, File directory, String propertiesKey )
809 FileOutputStream os = new FileOutputStream( new File( directory, propertiesKey + ".properties" ) );
812 properties.store( os, null );
816 IOUtils.closeQuietly( os );
820 public void setDirectory( File directory )
822 this.directory = directory;
825 public void setMetadataFacetFactories( Map<String, MetadataFacetFactory> metadataFacetFactories )
827 this.metadataFacetFactories = metadataFacetFactories;