blob: 6565f7512530a5d0d1f49151474b5b578c25f0ed [file] [log] [blame]
package org.apache.archiva.metadata.repository.file;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.archiva.metadata.model.ArtifactMetadata;
import org.apache.archiva.metadata.model.CiManagement;
import org.apache.archiva.metadata.model.Dependency;
import org.apache.archiva.metadata.model.IssueManagement;
import org.apache.archiva.metadata.model.License;
import org.apache.archiva.metadata.model.MailingList;
import org.apache.archiva.metadata.model.MetadataFacet;
import org.apache.archiva.metadata.model.MetadataFacetFactory;
import org.apache.archiva.metadata.model.Organization;
import org.apache.archiva.metadata.model.ProjectMetadata;
import org.apache.archiva.metadata.model.ProjectVersionMetadata;
import org.apache.archiva.metadata.model.ProjectVersionReference;
import org.apache.archiva.metadata.model.Scm;
import org.apache.archiva.metadata.repository.MetadataRepository;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
/**
* @plexus.component role="org.apache.archiva.metadata.repository.MetadataRepository"
*/
public class FileMetadataRepository
implements MetadataRepository
{
/**
* @plexus.requirement role="org.apache.archiva.metadata.model.MetadataFacetFactory"
*/
private Map<String, MetadataFacetFactory> metadataFacetFactories;
/**
* @plexus.requirement
*/
private ArchivaConfiguration configuration;
private static final Logger log = LoggerFactory.getLogger( FileMetadataRepository.class );
private static final String PROJECT_METADATA_KEY = "project-metadata";
private static final String PROJECT_VERSION_METADATA_KEY = "version-metadata";
private static final String NAMESPACE_METADATA_KEY = "namespace-metadata";
private static final String METADATA_KEY = "metadata";
private File getBaseDirectory( String repoId )
{
// TODO: should be configurable, like the index
String basedir = configuration.getConfiguration().getManagedRepositoriesAsMap().get( repoId ).getLocation();
File dir = new File( basedir, ".archiva" );
return dir;
}
private File getDirectory( String repoId )
{
return new File( getBaseDirectory( repoId ), "content" );
}
public void updateProject( String repoId, ProjectMetadata project )
{
updateProject( repoId, project.getNamespace(), project.getId() );
}
private void updateProject( String repoId, String namespace, String id )
{
// TODO: this is a more braindead implementation than we would normally expect, for prototyping purposes
updateNamespace( repoId, namespace );
try
{
File namespaceDirectory = new File( getDirectory( repoId ), namespace );
Properties properties = new Properties();
properties.setProperty( "namespace", namespace );
properties.setProperty( "id", id );
writeProperties( properties, new File( namespaceDirectory, id ), PROJECT_METADATA_KEY );
}
catch ( IOException e )
{
// TODO!
e.printStackTrace();
}
}
public void updateProjectVersion( String repoId, String namespace, String projectId,
ProjectVersionMetadata versionMetadata )
{
updateProject( repoId, namespace, projectId );
File directory = new File( getDirectory( repoId ),
namespace + "/" + projectId + "/" + versionMetadata.getId() );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
// remove properties that are not references or artifacts
for ( Object key : new ArrayList( properties.keySet() ) )
{
String name = (String) key;
if ( !name.contains( ":" ) && !name.equals( "facetIds" ) )
{
properties.remove( name );
}
}
properties.setProperty( "id", versionMetadata.getId() );
setProperty( properties, "name", versionMetadata.getName() );
setProperty( properties, "description", versionMetadata.getDescription() );
setProperty( properties, "url", versionMetadata.getUrl() );
setProperty( properties, "incomplete", String.valueOf( versionMetadata.isIncomplete() ) );
if ( versionMetadata.getScm() != null )
{
setProperty( properties, "scm.connection", versionMetadata.getScm().getConnection() );
setProperty( properties, "scm.developerConnection", versionMetadata.getScm().getDeveloperConnection() );
setProperty( properties, "scm.url", versionMetadata.getScm().getUrl() );
}
if ( versionMetadata.getCiManagement() != null )
{
setProperty( properties, "ci.system", versionMetadata.getCiManagement().getSystem() );
setProperty( properties, "ci.url", versionMetadata.getCiManagement().getUrl() );
}
if ( versionMetadata.getIssueManagement() != null )
{
setProperty( properties, "issue.system", versionMetadata.getIssueManagement().getSystem() );
setProperty( properties, "issue.url", versionMetadata.getIssueManagement().getUrl() );
}
if ( versionMetadata.getOrganization() != null )
{
setProperty( properties, "org.name", versionMetadata.getOrganization().getName() );
setProperty( properties, "org.url", versionMetadata.getOrganization().getUrl() );
}
int i = 0;
for ( License license : versionMetadata.getLicenses() )
{
setProperty( properties, "license." + i + ".name", license.getName() );
setProperty( properties, "license." + i + ".url", license.getUrl() );
i++;
}
i = 0;
for ( MailingList mailingList : versionMetadata.getMailingLists() )
{
setProperty( properties, "mailingList." + i + ".archive", mailingList.getMainArchiveUrl() );
setProperty( properties, "mailingList." + i + ".name", mailingList.getName() );
setProperty( properties, "mailingList." + i + ".post", mailingList.getPostAddress() );
setProperty( properties, "mailingList." + i + ".unsubscribe", mailingList.getUnsubscribeAddress() );
setProperty( properties, "mailingList." + i + ".subscribe", mailingList.getSubscribeAddress() );
setProperty( properties, "mailingList." + i + ".otherArchives", join( mailingList.getOtherArchives() ) );
i++;
}
i = 0;
for ( Dependency dependency : versionMetadata.getDependencies() )
{
setProperty( properties, "dependency." + i + ".classifier", dependency.getClassifier() );
setProperty( properties, "dependency." + i + ".scope", dependency.getScope() );
setProperty( properties, "dependency." + i + ".systemPath", dependency.getSystemPath() );
setProperty( properties, "dependency." + i + ".artifactId", dependency.getArtifactId() );
setProperty( properties, "dependency." + i + ".groupId", dependency.getGroupId() );
setProperty( properties, "dependency." + i + ".version", dependency.getVersion() );
setProperty( properties, "dependency." + i + ".type", dependency.getType() );
i++;
}
Set<String> facetIds = new LinkedHashSet<String>( versionMetadata.getFacetIds() );
facetIds.addAll( Arrays.asList( properties.getProperty( "facetIds", "" ).split( "," ) ) );
properties.setProperty( "facetIds", join( facetIds ) );
for ( MetadataFacet facet : versionMetadata.getFacetList() )
{
properties.putAll( facet.toProperties() );
}
try
{
writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public void updateProjectReference( String repoId, String namespace, String projectId, String projectVersion,
ProjectVersionReference reference )
{
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
int i = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
setProperty( properties, "ref:lastReferenceNum", Integer.toString( i ) );
setProperty( properties, "ref:reference." + i + ".namespace", reference.getNamespace() );
setProperty( properties, "ref:reference." + i + ".projectId", reference.getProjectId() );
setProperty( properties, "ref:reference." + i + ".projectVersion", reference.getProjectVersion() );
setProperty( properties, "ref:reference." + i + ".referenceType", reference.getReferenceType().toString() );
try
{
writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public void updateNamespace( String repoId, String namespace )
{
try
{
File namespaceDirectory = new File( getDirectory( repoId ), namespace );
Properties properties = new Properties();
properties.setProperty( "namespace", namespace );
writeProperties( properties, namespaceDirectory, NAMESPACE_METADATA_KEY );
}
catch ( IOException e )
{
// TODO!
e.printStackTrace();
}
}
public List<String> getMetadataFacets( String repoId, String facetId )
{
File directory = getMetadataDirectory( repoId, facetId );
List<String> facets = new ArrayList<String>();
recurse( facets, "", directory );
return facets;
}
private void recurse( List<String> facets, String prefix, File directory )
{
File[] list = directory.listFiles();
if ( list != null )
{
for ( File dir : list )
{
if ( dir.isDirectory() )
{
recurse( facets, prefix + "/" + dir.getName(), dir );
}
else if ( dir.getName().equals( METADATA_KEY + ".properties" ) )
{
facets.add( prefix.substring( 1 ) );
}
}
}
}
public MetadataFacet getMetadataFacet( String repositoryId, String facetId, String name )
{
Properties properties;
try
{
properties = readProperties( new File( getMetadataDirectory( repositoryId, facetId ), name ),
METADATA_KEY );
}
catch ( FileNotFoundException e )
{
return null;
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
return null;
}
MetadataFacet metadataFacet = null;
MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId );
if ( metadataFacetFactory != null )
{
metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
Map<String, String> map = new HashMap<String, String>();
for ( Object key : new ArrayList( properties.keySet() ) )
{
String property = (String) key;
map.put( property, properties.getProperty( property ) );
}
metadataFacet.fromProperties( map );
}
return metadataFacet;
}
public void addMetadataFacet( String repositoryId, MetadataFacet metadataFacet )
{
Properties properties = new Properties();
properties.putAll( metadataFacet.toProperties() );
try
{
File directory = new File( getMetadataDirectory( repositoryId, metadataFacet.getFacetId() ),
metadataFacet.getName() );
writeProperties( properties, directory, METADATA_KEY );
}
catch ( IOException e )
{
// TODO!
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public void removeMetadataFacets( String repositoryId, String facetId )
{
try
{
FileUtils.deleteDirectory( getMetadataDirectory( repositoryId, facetId ) );
}
catch ( IOException e )
{
// TODO!
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public void removeMetadataFacet( String repoId, String facetId, String name )
{
File dir = new File( getMetadataDirectory( repoId, facetId ), name );
try
{
FileUtils.deleteDirectory( dir );
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public List<ArtifactMetadata> getArtifactsByDateRange( String repoId, Date startTime, Date endTime )
{
// TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
// of this information (eg. in Lucene, as before)
List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
for ( String ns : getRootNamespaces( repoId ) )
{
getArtifactsByDateRange( artifacts, repoId, ns, startTime, endTime );
}
Collections.sort( artifacts, new ArtifactComparator() );
return artifacts;
}
private void getArtifactsByDateRange( List<ArtifactMetadata> artifacts, String repoId, String ns, Date startTime,
Date endTime )
{
for ( String namespace : getNamespaces( repoId, ns ) )
{
getArtifactsByDateRange( artifacts, repoId, ns + "." + namespace, startTime, endTime );
}
for ( String project : getProjects( repoId, ns ) )
{
for ( String version : getProjectVersions( repoId, ns, project ) )
{
for ( ArtifactMetadata artifact : getArtifacts( repoId, ns, project, version ) )
{
if ( startTime == null || startTime.before( artifact.getWhenGathered() ) )
{
if ( endTime == null || endTime.after( artifact.getWhenGathered() ) )
{
artifacts.add( artifact );
}
}
}
}
}
}
public Collection<ArtifactMetadata> getArtifacts( String repoId, String namespace, String projectId,
String projectVersion )
{
Map<String, ArtifactMetadata> artifacts = new HashMap<String, ArtifactMetadata>();
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
for ( Map.Entry entry : properties.entrySet() )
{
String name = (String) entry.getKey();
StringTokenizer tok = new StringTokenizer( name, ":" );
if ( tok.hasMoreTokens() && "artifact".equals( tok.nextToken() ) )
{
String field = tok.nextToken();
String id = tok.nextToken();
ArtifactMetadata artifact = artifacts.get( id );
if ( artifact == null )
{
artifact = new ArtifactMetadata();
artifact.setRepositoryId( repoId );
artifact.setNamespace( namespace );
artifact.setProject( projectId );
artifact.setVersion( projectVersion );
artifact.setId( id );
artifacts.put( id, artifact );
}
String value = (String) entry.getValue();
if ( "updated".equals( field ) )
{
artifact.setFileLastModified( Long.valueOf( value ) );
}
else if ( "size".equals( field ) )
{
artifact.setSize( Long.valueOf( value ) );
}
else if ( "whenGathered".equals( field ) )
{
artifact.setWhenGathered( new Date( Long.valueOf( value ) ) );
}
else if ( "version".equals( field ) )
{
artifact.setVersion( value );
}
else if ( "md5".equals( field ) )
{
artifact.setMd5( value );
}
else if ( "sha1".equals( field ) )
{
artifact.setSha1( value );
}
}
}
return artifacts.values();
}
public Collection<String> getRepositories()
{
return configuration.getConfiguration().getManagedRepositoriesAsMap().keySet();
}
public List<ArtifactMetadata> getArtifactsByChecksum( String repositoryId, String checksum )
{
// TODO: this is quite slow - if we are to persist with this repository implementation we should build an index
// of this information (eg. in Lucene, as before)
// alternatively, we could build a referential tree in the content repository, however it would need some levels
// of depth to avoid being too broad to be useful (eg. /repository/checksums/a/ab/abcdef1234567)
List<ArtifactMetadata> artifacts = new ArrayList<ArtifactMetadata>();
for ( String ns : getRootNamespaces( repositoryId ) )
{
getArtifactsByChecksum( artifacts, repositoryId, ns, checksum );
}
return artifacts;
}
public void deleteArtifact( String repoId, String namespace, String project, String version, String id )
{
File directory = new File( getDirectory( repoId ), namespace + "/" + project + "/" + version );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
properties.remove( "artifact:updated:" + id );
properties.remove( "artifact:whenGathered:" + id );
properties.remove( "artifact:size:" + id );
properties.remove( "artifact:md5:" + id );
properties.remove( "artifact:sha1:" + id );
properties.remove( "artifact:version:" + id );
try
{
writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
public void deleteRepository( String repoId )
{
try
{
FileUtils.deleteDirectory( getDirectory( repoId ) );
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
private void getArtifactsByChecksum( List<ArtifactMetadata> artifacts, String repositoryId, String ns,
String checksum )
{
for ( String namespace : getNamespaces( repositoryId, ns ) )
{
getArtifactsByChecksum( artifacts, repositoryId, ns + "." + namespace, checksum );
}
for ( String project : getProjects( repositoryId, ns ) )
{
for ( String version : getProjectVersions( repositoryId, ns, project ) )
{
for ( ArtifactMetadata artifact : getArtifacts( repositoryId, ns, project, version ) )
{
if ( checksum.equals( artifact.getMd5() ) || checksum.equals( artifact.getSha1() ) )
{
artifacts.add( artifact );
}
}
}
}
}
private File getMetadataDirectory( String repoId, String facetId )
{
return new File( getBaseDirectory( repoId ), "facets/" + facetId );
}
private String join( Collection<String> ids )
{
if ( !ids.isEmpty() )
{
StringBuilder s = new StringBuilder();
for ( String id : ids )
{
s.append( id );
s.append( "," );
}
return s.substring( 0, s.length() - 1 );
}
return "";
}
private void setProperty( Properties properties, String name, String value )
{
if ( value != null )
{
properties.setProperty( name, value );
}
}
public void updateArtifact( String repoId, String namespace, String projectId, String projectVersion,
ArtifactMetadata artifact )
{
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
properties.setProperty( "artifact:updated:" + artifact.getId(), Long.toString(
artifact.getFileLastModified().getTime() ) );
properties.setProperty( "artifact:whenGathered:" + artifact.getId(), Long.toString(
artifact.getWhenGathered().getTime() ) );
properties.setProperty( "artifact:size:" + artifact.getId(), Long.toString( artifact.getSize() ) );
if ( artifact.getMd5() != null )
{
properties.setProperty( "artifact:md5:" + artifact.getId(), artifact.getMd5() );
}
if ( artifact.getSha1() != null )
{
properties.setProperty( "artifact:sha1:" + artifact.getId(), artifact.getSha1() );
}
properties.setProperty( "artifact:version:" + artifact.getId(), artifact.getVersion() );
try
{
writeProperties( properties, directory, PROJECT_VERSION_METADATA_KEY );
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
private Properties readOrCreateProperties( File directory, String propertiesKey )
{
try
{
return readProperties( directory, propertiesKey );
}
catch ( FileNotFoundException e )
{
// ignore and return new properties
}
catch ( IOException e )
{
// TODO
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
return new Properties();
}
private Properties readProperties( File directory, String propertiesKey )
throws IOException
{
Properties properties = new Properties();
FileInputStream in = null;
try
{
in = new FileInputStream( new File( directory, propertiesKey + ".properties" ) );
properties.load( in );
}
finally
{
IOUtils.closeQuietly( in );
}
return properties;
}
public ProjectMetadata getProject( String repoId, String namespace, String projectId )
{
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
ProjectMetadata project = new ProjectMetadata();
project.setNamespace( properties.getProperty( "namespace" ) );
project.setId( properties.getProperty( "id" ) );
return project;
}
public ProjectVersionMetadata getProjectVersion( String repoId, String namespace, String projectId,
String projectVersion )
{
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
String id = properties.getProperty( "id" );
ProjectVersionMetadata versionMetadata = null;
if ( id != null )
{
versionMetadata = new ProjectVersionMetadata();
versionMetadata.setId( id );
versionMetadata.setName( properties.getProperty( "name" ) );
versionMetadata.setDescription( properties.getProperty( "description" ) );
versionMetadata.setUrl( properties.getProperty( "url" ) );
versionMetadata.setIncomplete( Boolean.valueOf( properties.getProperty( "incomplete", "false" ) ) );
String scmConnection = properties.getProperty( "scm.connection" );
String scmDeveloperConnection = properties.getProperty( "scm.developerConnection" );
String scmUrl = properties.getProperty( "scm.url" );
if ( scmConnection != null || scmDeveloperConnection != null || scmUrl != null )
{
Scm scm = new Scm();
scm.setConnection( scmConnection );
scm.setDeveloperConnection( scmDeveloperConnection );
scm.setUrl( scmUrl );
versionMetadata.setScm( scm );
}
String ciSystem = properties.getProperty( "ci.system" );
String ciUrl = properties.getProperty( "ci.url" );
if ( ciSystem != null || ciUrl != null )
{
CiManagement ci = new CiManagement();
ci.setSystem( ciSystem );
ci.setUrl( ciUrl );
versionMetadata.setCiManagement( ci );
}
String issueSystem = properties.getProperty( "issue.system" );
String issueUrl = properties.getProperty( "issue.url" );
if ( issueSystem != null || issueUrl != null )
{
IssueManagement issueManagement = new IssueManagement();
issueManagement.setSystem( issueSystem );
issueManagement.setUrl( issueUrl );
versionMetadata.setIssueManagement( issueManagement );
}
String orgName = properties.getProperty( "org.name" );
String orgUrl = properties.getProperty( "org.url" );
if ( orgName != null || orgUrl != null )
{
Organization org = new Organization();
org.setName( orgName );
org.setUrl( orgUrl );
versionMetadata.setOrganization( org );
}
boolean done = false;
int i = 0;
while ( !done )
{
String licenseName = properties.getProperty( "license." + i + ".name" );
String licenseUrl = properties.getProperty( "license." + i + ".url" );
if ( licenseName != null || licenseUrl != null )
{
License license = new License();
license.setName( licenseName );
license.setUrl( licenseUrl );
versionMetadata.addLicense( license );
}
else
{
done = true;
}
i++;
}
done = false;
i = 0;
while ( !done )
{
String mailingListName = properties.getProperty( "mailingList." + i + ".name" );
if ( mailingListName != null )
{
MailingList mailingList = new MailingList();
mailingList.setName( mailingListName );
mailingList.setMainArchiveUrl( properties.getProperty( "mailingList." + i + ".archive" ) );
mailingList.setOtherArchives( Arrays.asList( properties.getProperty(
"mailingList." + i + ".otherArchives" ).split( "," ) ) );
mailingList.setPostAddress( properties.getProperty( "mailingList." + i + ".post" ) );
mailingList.setSubscribeAddress( properties.getProperty( "mailingList." + i + ".subscribe" ) );
mailingList.setUnsubscribeAddress( properties.getProperty( "mailingList." + i + ".unsubscribe" ) );
versionMetadata.addMailingList( mailingList );
}
else
{
done = true;
}
i++;
}
done = false;
i = 0;
while ( !done )
{
String dependencyArtifactId = properties.getProperty( "dependency." + i + ".artifactId" );
if ( dependencyArtifactId != null )
{
Dependency dependency = new Dependency();
dependency.setArtifactId( dependencyArtifactId );
dependency.setGroupId( properties.getProperty( "dependency." + i + ".groupId" ) );
dependency.setClassifier( properties.getProperty( "dependency." + i + ".classifier" ) );
dependency.setOptional( Boolean.valueOf( properties.getProperty(
"dependency." + i + ".optional" ) ) );
dependency.setScope( properties.getProperty( "dependency." + i + ".scope" ) );
dependency.setSystemPath( properties.getProperty( "dependency." + i + ".systemPath" ) );
dependency.setType( properties.getProperty( "dependency." + i + ".type" ) );
dependency.setVersion( properties.getProperty( "dependency." + i + ".version" ) );
versionMetadata.addDependency( dependency );
}
else
{
done = true;
}
i++;
}
String facetIds = properties.getProperty( "facetIds", "" );
if ( facetIds.length() > 0 )
{
for ( String facetId : facetIds.split( "," ) )
{
MetadataFacetFactory factory = metadataFacetFactories.get( facetId );
if ( factory == null )
{
log.error( "Attempted to load unknown metadata facet: " + facetId );
}
else
{
MetadataFacet facet = factory.createMetadataFacet();
Map<String, String> map = new HashMap<String, String>();
for ( Object key : new ArrayList( properties.keySet() ) )
{
String property = (String) key;
if ( property.startsWith( facet.getFacetId() ) )
{
map.put( property, properties.getProperty( property ) );
}
}
facet.fromProperties( map );
versionMetadata.addFacet( facet );
}
}
}
for ( MetadataFacet facet : versionMetadata.getFacetList() )
{
properties.putAll( facet.toProperties() );
}
}
return versionMetadata;
}
public Collection<String> getArtifactVersions( String repoId, String namespace, String projectId,
String projectVersion )
{
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
Set<String> versions = new HashSet<String>();
for ( Map.Entry entry : properties.entrySet() )
{
String name = (String) entry.getKey();
if ( name.startsWith( "artifact:version:" ) )
{
versions.add( (String) entry.getValue() );
}
}
return versions;
}
public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId,
String projectVersion )
{
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId + "/" + projectVersion );
Properties properties = readOrCreateProperties( directory, PROJECT_VERSION_METADATA_KEY );
int numberOfRefs = Integer.valueOf( properties.getProperty( "ref:lastReferenceNum", "-1" ) ) + 1;
List<ProjectVersionReference> references = new ArrayList<ProjectVersionReference>();
for ( int i = 0; i < numberOfRefs; i++ )
{
ProjectVersionReference reference = new ProjectVersionReference();
reference.setProjectId( properties.getProperty( "ref:reference." + i + ".projectId" ) );
reference.setNamespace( properties.getProperty( "ref:reference." + i + ".namespace" ) );
reference.setProjectVersion( properties.getProperty( "ref:reference." + i + ".projectVersion" ) );
reference.setReferenceType( ProjectVersionReference.ReferenceType.valueOf( properties.getProperty(
"ref:reference." + i + ".referenceType" ) ) );
references.add( reference );
}
return references;
}
public Collection<String> getRootNamespaces( String repoId )
{
return getNamespaces( repoId, null );
}
public Collection<String> getNamespaces( String repoId, String baseNamespace )
{
List<String> allNamespaces = new ArrayList<String>();
File directory = getDirectory( repoId );
File[] files = directory.listFiles();
if ( files != null )
{
for ( File namespace : files )
{
if ( new File( namespace, NAMESPACE_METADATA_KEY + ".properties" ).exists() )
{
allNamespaces.add( namespace.getName() );
}
}
}
Set<String> namespaces = new LinkedHashSet<String>();
int fromIndex = baseNamespace != null ? baseNamespace.length() + 1 : 0;
for ( String namespace : allNamespaces )
{
if ( baseNamespace == null || namespace.startsWith( baseNamespace + "." ) )
{
int i = namespace.indexOf( '.', fromIndex );
if ( i >= 0 )
{
namespaces.add( namespace.substring( fromIndex, i ) );
}
else
{
namespaces.add( namespace.substring( fromIndex ) );
}
}
}
return new ArrayList<String>( namespaces );
}
public Collection<String> getProjects( String repoId, String namespace )
{
List<String> projects = new ArrayList<String>();
File directory = new File( getDirectory( repoId ), namespace );
File[] files = directory.listFiles();
if ( files != null )
{
for ( File project : files )
{
if ( new File( project, PROJECT_METADATA_KEY + ".properties" ).exists() )
{
projects.add( project.getName() );
}
}
}
return projects;
}
public Collection<String> getProjectVersions( String repoId, String namespace, String projectId )
{
List<String> projectVersions = new ArrayList<String>();
File directory = new File( getDirectory( repoId ), namespace + "/" + projectId );
File[] files = directory.listFiles();
if ( files != null )
{
for ( File projectVersion : files )
{
if ( new File( projectVersion, PROJECT_VERSION_METADATA_KEY + ".properties" ).exists() )
{
projectVersions.add( projectVersion.getName() );
}
}
}
return projectVersions;
}
private void writeProperties( Properties properties, File directory, String propertiesKey )
throws IOException
{
directory.mkdirs();
FileOutputStream os = new FileOutputStream( new File( directory, propertiesKey + ".properties" ) );
try
{
properties.store( os, null );
}
finally
{
IOUtils.closeQuietly( os );
}
}
public void setMetadataFacetFactories( Map<String, MetadataFacetFactory> metadataFacetFactories )
{
this.metadataFacetFactories = metadataFacetFactories;
}
public void setConfiguration( ArchivaConfiguration configuration )
{
this.configuration = configuration;
}
private static class ArtifactComparator
implements Comparator<ArtifactMetadata>
{
public int compare( ArtifactMetadata artifact1, ArtifactMetadata artifact2 )
{
if ( artifact1.getWhenGathered() == artifact2.getWhenGathered() )
{
return 0;
}
if ( artifact1.getWhenGathered() == null )
{
return 1;
}
if ( artifact2.getWhenGathered() == null )
{
return -1;
}
return artifact1.getWhenGathered().compareTo( artifact2.getWhenGathered() );
}
}
}