<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-utils</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-repository-layer</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-indexer</artifactId>
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
-import org.apache.maven.artifact.repository.metadata.Metadata;
-import org.apache.maven.artifact.repository.metadata.Snapshot;
-import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
-import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.List;
-
-/**
- *
- */
-public abstract class AbstractRepositoryQueryLayer
- implements RepositoryQueryLayer
-{
- protected ArtifactRepository repository;
-
- public boolean containsArtifact( Artifact artifact )
- {
- File f = new File( repository.getBasedir(), repository.pathOf( artifact ) );
- return f.exists();
- }
-
- public boolean containsArtifact( Artifact artifact, Snapshot snapshot )
- {
- String artifactPath = getSnapshotArtifactRepositoryPath( artifact, snapshot );
- File artifactFile = new File( artifactPath );
- return artifactFile.exists();
- }
-
- public List getVersions( Artifact artifact )
- throws RepositoryQueryLayerException
- {
- Metadata metadata = getMetadata( artifact );
-
- return metadata.getVersioning().getVersions();
- }
-
- protected String getSnapshotArtifactRepositoryPath( Artifact artifact, Snapshot snapshot )
- {
- File f = new File( repository.getBasedir(), repository.pathOf( artifact ) );
- String snapshotInfo = artifact.getVersion().replaceFirst( "SNAPSHOT", snapshot.getTimestamp() + "-" +
- snapshot.getBuildNumber() + ".pom" );
- File snapshotFile = new File( f.getParentFile(), artifact.getArtifactId() + "-" + snapshotInfo );
- return snapshotFile.getAbsolutePath();
- }
-
- protected Metadata getMetadata( Artifact artifact )
- throws RepositoryQueryLayerException
- {
- Metadata metadata;
-
- ArtifactRepositoryMetadata repositoryMetadata = new ArtifactRepositoryMetadata( artifact );
- String path = repository.pathOfRemoteRepositoryMetadata( repositoryMetadata );
- File metadataFile = new File( repository.getBasedir(), path );
- if ( metadataFile.exists() )
- {
- MetadataXpp3Reader reader = new MetadataXpp3Reader();
- try
- {
- metadata = reader.read( new FileReader( metadataFile ) );
- }
- catch ( FileNotFoundException e )
- {
- throw new RepositoryQueryLayerException( "Error occurred while attempting to read metadata file", e );
- }
- catch ( IOException e )
- {
- throw new RepositoryQueryLayerException( "Error occurred while attempting to read metadata file", e );
- }
- catch ( XmlPullParserException e )
- {
- throw new RepositoryQueryLayerException( "Error occurred while attempting to read metadata file", e );
- }
- }
- else
- {
- throw new RepositoryQueryLayerException( "Metadata not found: " + metadataFile.getAbsolutePath() );
- }
-
- return metadata;
- }
-}
* limitations under the License.
*/
+import org.apache.maven.archiva.layer.RepositoryQueryLayer;
+import org.apache.maven.archiva.layer.RepositoryQueryLayerFactory;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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 java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Class to implement caching.
- */
-public class Cache
-{
- private final Map cache;
-
- private final double cacheHitRatio;
-
- private final int cacheMaxSize;
-
- private long cacheHits;
-
- private long cacheMiss;
-
- /**
- * Caches all data and expires only the oldest data when the specified cache hit rate is reached.
- */
- public Cache( double cacheHitRatio )
- {
- this( cacheHitRatio, 0 );
- }
-
- /**
- * Caches all data and expires only the oldest data when the maximum cache size is reached
- */
- public Cache( int cacheMaxSize )
- {
- this( (double) 1, cacheMaxSize );
- }
-
- /**
- * Caches all data and expires only the oldest data when either the specified cache hit rate is reached
- * or the maximum cache size is reached.
- */
- public Cache( double cacheHitRatio, int cacheMaxSize )
- {
- this.cacheHitRatio = cacheHitRatio;
- this.cacheMaxSize = cacheMaxSize;
-
- if ( cacheMaxSize > 0 )
- {
- cache = new LinkedHashMap( cacheMaxSize );
- }
- else
- {
- cache = new LinkedHashMap();
- }
- }
-
- /**
- * Check if the specified key is already mapped to an object.
- *
- * @param key the key used to map the cached object
- * @return true if the cache contains an object associated with the given key
- */
- public boolean containsKey( Object key )
- {
- boolean contains;
- synchronized ( cache )
- {
- contains = cache.containsKey( key );
-
- if ( contains )
- {
- cacheHits++;
- }
- else
- {
- cacheMiss++;
- }
- }
-
- return contains;
- }
-
- /**
- * Check for a cached object and return it if it exists. Returns null when the keyed object is not found
- *
- * @param key the key used to map the cached object
- * @return the object mapped to the given key, or null if no cache object is mapped to the given key
- */
- public Object get( Object key )
- {
- Object retValue = null;
-
- synchronized ( cache )
- {
- if ( cache.containsKey( key ) )
- {
- // remove and put: this promotes it to the top since we use a linked hash map
- retValue = cache.remove( key );
-
- cache.put( key, retValue );
-
- cacheHits++;
- }
- else
- {
- cacheMiss++;
- }
- }
-
- return retValue;
- }
-
- /**
- * Cache the given value and map it using the given key
- *
- * @param key the object to map the valued object
- * @param value the object to cache
- */
- public void put( Object key, Object value )
- {
- // remove and put: this promotes it to the top since we use a linked hash map
- synchronized ( cache )
- {
- if ( cache.containsKey( key ) )
- {
- cache.remove( key );
- }
-
- cache.put( key, value );
- }
-
- manageCache();
- }
-
- /**
- * Compute for the efficiency of this cache.
- *
- * @return the ratio of cache hits to the cache misses to queries for cache objects
- */
- public double getHitRate()
- {
- synchronized ( cache )
- {
- return cacheHits == 0 && cacheMiss == 0 ? 0 : (double) cacheHits / (double) ( cacheHits + cacheMiss );
- }
- }
-
- /**
- * Get the total number of cache objects currently cached.
- */
- public int size()
- {
- return cache.size();
- }
-
- /**
- * Empty the cache and reset the cache hit rate
- */
- public void clear()
- {
- synchronized ( cache )
- {
- cacheHits = 0;
- cacheMiss = 0;
- cache.clear();
- }
- }
-
- private void manageCache()
- {
- synchronized ( cache )
- {
- Iterator iterator = cache.entrySet().iterator();
- if ( cacheMaxSize == 0 )
- {
- //desired HitRatio is reached, we can trim the cache to conserve memory
- if ( cacheHitRatio <= getHitRate() )
- {
- iterator.next();
- iterator.remove();
- }
- }
- else if ( cache.size() > cacheMaxSize )
- {
- // maximum cache size is reached
- while ( cache.size() > cacheMaxSize )
- {
- iterator.next();
- iterator.remove();
- }
- }
- else
- {
- //even though the max has not been reached, the desired HitRatio is already reached,
- // so we can trim the cache to conserve memory
- if ( cacheHitRatio <= getHitRate() )
- {
- iterator.next();
- iterator.remove();
- }
- }
- }
- }
-
-}
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.ArtifactRepository;
-import org.apache.maven.artifact.repository.metadata.Metadata;
-import org.apache.maven.artifact.repository.metadata.Snapshot;
-
-
-/**
- *
- */
-public class CachedRepositoryQueryLayer
- extends AbstractRepositoryQueryLayer
-{
- private Cache cache;
-
- public static final double CACHE_HIT_RATIO = 0.5;
-
- public CachedRepositoryQueryLayer( ArtifactRepository repository )
- {
- this.repository = repository;
-
- cache = new Cache( CACHE_HIT_RATIO );
- }
-
- public double getCacheHitRate()
- {
- return cache.getHitRate();
- }
-
- public boolean containsArtifact( Artifact artifact )
- {
- boolean artifactFound = true;
-
- String artifactPath = repository.getBasedir() + "/" + repository.pathOf( artifact );
-
- if ( cache.get( artifactPath ) == null )
- {
- artifactFound = super.containsArtifact( artifact );
- if ( artifactFound )
- {
- cache.put( artifactPath, artifactPath );
- }
- }
-
- return artifactFound;
- }
-
- public boolean containsArtifact( Artifact artifact, Snapshot snapshot )
- {
- boolean artifactFound = true;
-
- String path = getSnapshotArtifactRepositoryPath( artifact, snapshot );
-
- if ( cache.get( path ) == null )
- {
- artifactFound = super.containsArtifact( artifact, snapshot );
- if ( artifactFound )
- {
- cache.put( path, path );
- }
- }
-
- return artifactFound;
- }
-
- /**
- * Override method to utilize the cache
- */
- protected Metadata getMetadata( Artifact artifact )
- throws RepositoryQueryLayerException
- {
- Metadata metadata = (Metadata) cache.get( artifact.getId() );
-
- if ( metadata == null )
- {
- metadata = super.getMetadata( artifact );
- cache.put( artifact.getId(), metadata );
- }
-
- return metadata;
- }
-}
* limitations under the License.
*/
+import org.apache.maven.archiva.layer.RepositoryQueryLayer;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.maven.artifact.repository.ArtifactRepository;
-
-/**
- *
- */
-public class DefaultRepositoryQueryLayer
- extends AbstractRepositoryQueryLayer
-{
- public DefaultRepositoryQueryLayer( ArtifactRepository repository )
- {
- this.repository = repository;
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.maven.artifact.repository.ArtifactRepository;
-
-/**
- * Gets the default implementation of a repository query layer for the given repository.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @version $Id$
- * @plexus.component role="org.apache.maven.archiva.reporting.RepositoryQueryLayerFactory"
- */
-public class DefaultRepositoryQueryLayerFactory
- implements RepositoryQueryLayerFactory
-{
- public RepositoryQueryLayer createRepositoryQueryLayer( ArtifactRepository repository )
- {
- return new DefaultRepositoryQueryLayer( repository );
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.maven.artifact.Artifact;
-import org.apache.maven.artifact.repository.metadata.Snapshot;
-
-import java.util.List;
-
-/**
- * The transitive and metadata validation reports will need to query the repository for artifacts.
- */
-public interface RepositoryQueryLayer
-{
- String ROLE = RepositoryQueryLayer.class.getName();
-
- boolean containsArtifact( Artifact artifact );
-
- /**
- * @todo I believe we can remove this [BP] - artifact should contain all the necessary version info!
- */
- boolean containsArtifact( Artifact artifact, Snapshot snapshot );
-
- List getVersions( Artifact artifact )
- throws RepositoryQueryLayerException;
-}
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.
- */
-
-/**
- *
- */
-public class RepositoryQueryLayerException
- extends Exception
-{
- public RepositoryQueryLayerException( String message, Throwable cause )
- {
- super( message, cause );
- }
-
- public RepositoryQueryLayerException( String message )
- {
- super( message );
- }
-}
+++ /dev/null
-package org.apache.maven.archiva.reporting;
-
-/*
- * Copyright 2005-2006 The Apache Software Foundation.
- *
- * Licensed 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.maven.artifact.repository.ArtifactRepository;
-
-/**
- * Gets the preferred implementation of a repository query layer for the given repository.
- *
- * @author <a href="mailto:brett@apache.org">Brett Porter</a>
- * @version $Id$
- */
-public interface RepositoryQueryLayerFactory
-{
- String ROLE = RepositoryQueryLayerFactory.class.getName();
-
- /**
- * Create or obtain a query interface.
- *
- * @param repository the repository to query
- * @return the obtained query layer
- */
- RepositoryQueryLayer createRepositoryQueryLayer( ArtifactRepository repository );
-}
* limitations under the License.
*/
+import org.apache.maven.archiva.layer.CachedRepositoryQueryLayer;
+import org.apache.maven.archiva.layer.RepositoryQueryLayerException;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.repository.ArtifactRepository;
*/
import junit.framework.TestCase;
+import org.apache.maven.archiva.layer.Cache;
/**
*
package org.apache.maven.archiva.reporting;
+import org.apache.maven.archiva.layer.CachedRepositoryQueryLayer;
+
/*
* Copyright 2005-2006 The Apache Software Foundation.
*
* limitations under the License.
*/
+import org.apache.maven.archiva.layer.RepositoryQueryLayer;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.metadata.Snapshot;
import java.util.List;
/**
- *
+ *
*/
public class MockRepositoryQueryLayer
implements RepositoryQueryLayer
--- /dev/null
+<?xml version="1.0"?>
+
+<!--
+ ~ Copyright 2005-2006 The Apache Software Foundation.
+ ~
+ ~ Licensed 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.
+ -->
+
+<project>
+ <parent>
+ <artifactId>archiva</artifactId>
+ <groupId>org.apache.maven.archiva</groupId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-repository-layer</artifactId>
+ <name>Archiva Repository Interface Layer</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact-manager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-repository-metadata</artifactId>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ *
+ */
+public abstract class AbstractRepositoryQueryLayer
+ implements RepositoryQueryLayer
+{
+ protected ArtifactRepository repository;
+
+ public boolean containsArtifact( Artifact artifact )
+ {
+ File f = new File( repository.getBasedir(), repository.pathOf( artifact ) );
+ return f.exists();
+ }
+
+ public boolean containsArtifact( Artifact artifact, Snapshot snapshot )
+ {
+ String artifactPath = getSnapshotArtifactRepositoryPath( artifact, snapshot );
+ File artifactFile = new File( artifactPath );
+ return artifactFile.exists();
+ }
+
+ public List getVersions( Artifact artifact )
+ throws RepositoryQueryLayerException
+ {
+ Metadata metadata = getMetadata( artifact );
+
+ return metadata.getVersioning().getVersions();
+ }
+
+ protected String getSnapshotArtifactRepositoryPath( Artifact artifact, Snapshot snapshot )
+ {
+ File f = new File( repository.getBasedir(), repository.pathOf( artifact ) );
+ String snapshotInfo = artifact.getVersion().replaceFirst( "SNAPSHOT", snapshot.getTimestamp() + "-" +
+ snapshot.getBuildNumber() + ".pom" );
+ File snapshotFile = new File( f.getParentFile(), artifact.getArtifactId() + "-" + snapshotInfo );
+ return snapshotFile.getAbsolutePath();
+ }
+
+ protected Metadata getMetadata( Artifact artifact )
+ throws RepositoryQueryLayerException
+ {
+ Metadata metadata;
+
+ ArtifactRepositoryMetadata repositoryMetadata = new ArtifactRepositoryMetadata( artifact );
+ String path = repository.pathOfRemoteRepositoryMetadata( repositoryMetadata );
+ File metadataFile = new File( repository.getBasedir(), path );
+ if ( metadataFile.exists() )
+ {
+ MetadataXpp3Reader reader = new MetadataXpp3Reader();
+ try
+ {
+ metadata = reader.read( new FileReader( metadataFile ) );
+ }
+ catch ( FileNotFoundException e )
+ {
+ throw new RepositoryQueryLayerException( "Error occurred while attempting to read metadata file", e );
+ }
+ catch ( IOException e )
+ {
+ throw new RepositoryQueryLayerException( "Error occurred while attempting to read metadata file", e );
+ }
+ catch ( XmlPullParserException e )
+ {
+ throw new RepositoryQueryLayerException( "Error occurred while attempting to read metadata file", e );
+ }
+ }
+ else
+ {
+ throw new RepositoryQueryLayerException( "Metadata not found: " + metadataFile.getAbsolutePath() );
+ }
+
+ return metadata;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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 java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Class to implement caching.
+ */
+public class Cache
+{
+ private final Map cache;
+
+ private final double cacheHitRatio;
+
+ private final int cacheMaxSize;
+
+ private long cacheHits;
+
+ private long cacheMiss;
+
+ /**
+ * Caches all data and expires only the oldest data when the specified cache hit rate is reached.
+ */
+ public Cache( double cacheHitRatio )
+ {
+ this( cacheHitRatio, 0 );
+ }
+
+ /**
+ * Caches all data and expires only the oldest data when the maximum cache size is reached
+ */
+ public Cache( int cacheMaxSize )
+ {
+ this( (double) 1, cacheMaxSize );
+ }
+
+ /**
+ * Caches all data and expires only the oldest data when either the specified cache hit rate is reached
+ * or the maximum cache size is reached.
+ */
+ public Cache( double cacheHitRatio, int cacheMaxSize )
+ {
+ this.cacheHitRatio = cacheHitRatio;
+ this.cacheMaxSize = cacheMaxSize;
+
+ if ( cacheMaxSize > 0 )
+ {
+ cache = new LinkedHashMap( cacheMaxSize );
+ }
+ else
+ {
+ cache = new LinkedHashMap();
+ }
+ }
+
+ /**
+ * Check if the specified key is already mapped to an object.
+ *
+ * @param key the key used to map the cached object
+ * @return true if the cache contains an object associated with the given key
+ */
+ public boolean containsKey( Object key )
+ {
+ boolean contains;
+ synchronized ( cache )
+ {
+ contains = cache.containsKey( key );
+
+ if ( contains )
+ {
+ cacheHits++;
+ }
+ else
+ {
+ cacheMiss++;
+ }
+ }
+
+ return contains;
+ }
+
+ /**
+ * Check for a cached object and return it if it exists. Returns null when the keyed object is not found
+ *
+ * @param key the key used to map the cached object
+ * @return the object mapped to the given key, or null if no cache object is mapped to the given key
+ */
+ public Object get( Object key )
+ {
+ Object retValue = null;
+
+ synchronized ( cache )
+ {
+ if ( cache.containsKey( key ) )
+ {
+ // remove and put: this promotes it to the top since we use a linked hash map
+ retValue = cache.remove( key );
+
+ cache.put( key, retValue );
+
+ cacheHits++;
+ }
+ else
+ {
+ cacheMiss++;
+ }
+ }
+
+ return retValue;
+ }
+
+ /**
+ * Cache the given value and map it using the given key
+ *
+ * @param key the object to map the valued object
+ * @param value the object to cache
+ */
+ public void put( Object key, Object value )
+ {
+ // remove and put: this promotes it to the top since we use a linked hash map
+ synchronized ( cache )
+ {
+ if ( cache.containsKey( key ) )
+ {
+ cache.remove( key );
+ }
+
+ cache.put( key, value );
+ }
+
+ manageCache();
+ }
+
+ /**
+ * Compute for the efficiency of this cache.
+ *
+ * @return the ratio of cache hits to the cache misses to queries for cache objects
+ */
+ public double getHitRate()
+ {
+ synchronized ( cache )
+ {
+ return cacheHits == 0 && cacheMiss == 0 ? 0 : (double) cacheHits / (double) ( cacheHits + cacheMiss );
+ }
+ }
+
+ /**
+ * Get the total number of cache objects currently cached.
+ */
+ public int size()
+ {
+ return cache.size();
+ }
+
+ /**
+ * Empty the cache and reset the cache hit rate
+ */
+ public void clear()
+ {
+ synchronized ( cache )
+ {
+ cacheHits = 0;
+ cacheMiss = 0;
+ cache.clear();
+ }
+ }
+
+ private void manageCache()
+ {
+ synchronized ( cache )
+ {
+ Iterator iterator = cache.entrySet().iterator();
+ if ( cacheMaxSize == 0 )
+ {
+ //desired HitRatio is reached, we can trim the cache to conserve memory
+ if ( cacheHitRatio <= getHitRate() )
+ {
+ iterator.next();
+ iterator.remove();
+ }
+ }
+ else if ( cache.size() > cacheMaxSize )
+ {
+ // maximum cache size is reached
+ while ( cache.size() > cacheMaxSize )
+ {
+ iterator.next();
+ iterator.remove();
+ }
+ }
+ else
+ {
+ //even though the max has not been reached, the desired HitRatio is already reached,
+ // so we can trim the cache to conserve memory
+ if ( cacheHitRatio <= getHitRate() )
+ {
+ iterator.next();
+ iterator.remove();
+ }
+ }
+ }
+ }
+
+}
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.repository.metadata.Metadata;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+
+
+/**
+ *
+ */
+public class CachedRepositoryQueryLayer
+ extends AbstractRepositoryQueryLayer
+{
+ private Cache cache;
+
+ public static final double CACHE_HIT_RATIO = 0.5;
+
+ public CachedRepositoryQueryLayer( ArtifactRepository repository )
+ {
+ this.repository = repository;
+
+ cache = new Cache( CACHE_HIT_RATIO );
+ }
+
+ public double getCacheHitRate()
+ {
+ return cache.getHitRate();
+ }
+
+ public boolean containsArtifact( Artifact artifact )
+ {
+ boolean artifactFound = true;
+
+ String artifactPath = repository.getBasedir() + "/" + repository.pathOf( artifact );
+
+ if ( cache.get( artifactPath ) == null )
+ {
+ artifactFound = super.containsArtifact( artifact );
+ if ( artifactFound )
+ {
+ cache.put( artifactPath, artifactPath );
+ }
+ }
+
+ return artifactFound;
+ }
+
+ public boolean containsArtifact( Artifact artifact, Snapshot snapshot )
+ {
+ boolean artifactFound = true;
+
+ String path = getSnapshotArtifactRepositoryPath( artifact, snapshot );
+
+ if ( cache.get( path ) == null )
+ {
+ artifactFound = super.containsArtifact( artifact, snapshot );
+ if ( artifactFound )
+ {
+ cache.put( path, path );
+ }
+ }
+
+ return artifactFound;
+ }
+
+ /**
+ * Override method to utilize the cache
+ */
+ protected Metadata getMetadata( Artifact artifact )
+ throws RepositoryQueryLayerException
+ {
+ Metadata metadata = (Metadata) cache.get( artifact.getId() );
+
+ if ( metadata == null )
+ {
+ metadata = super.getMetadata( artifact );
+ cache.put( artifact.getId(), metadata );
+ }
+
+ return metadata;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.maven.artifact.repository.ArtifactRepository;
+
+/**
+ *
+ */
+public class DefaultRepositoryQueryLayer
+ extends AbstractRepositoryQueryLayer
+{
+ public DefaultRepositoryQueryLayer( ArtifactRepository repository )
+ {
+ this.repository = repository;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * Gets the default implementation of a repository query layer for the given repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @version $Id:DefaultRepositoryQueryLayerFactory.java 437105 2006-08-26 17:22:22 +1000 (Sat, 26 Aug 2006) brett $
+ * @plexus.component role="org.apache.maven.archiva.layer.RepositoryQueryLayerFactory"
+ */
+public class DefaultRepositoryQueryLayerFactory
+ implements RepositoryQueryLayerFactory
+{
+ public RepositoryQueryLayer createRepositoryQueryLayer( ArtifactRepository repository )
+ {
+ return new DefaultRepositoryQueryLayer( repository );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.metadata.Snapshot;
+
+import java.util.List;
+
+/**
+ * The transitive and metadata validation reports will need to query the repository for artifacts.
+ */
+public interface RepositoryQueryLayer
+{
+ String ROLE = RepositoryQueryLayer.class.getName();
+
+ boolean containsArtifact( Artifact artifact );
+
+ boolean containsArtifact( Artifact artifact, Snapshot snapshot );
+
+ List getVersions( Artifact artifact )
+ throws RepositoryQueryLayerException;
+}
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
+
+/**
+ *
+ */
+public class RepositoryQueryLayerException
+ extends Exception
+{
+ public RepositoryQueryLayerException( String message, Throwable cause )
+ {
+ super( message, cause );
+ }
+
+ public RepositoryQueryLayerException( String message )
+ {
+ super( message );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.layer;
+
+/*
+ * Copyright 2005-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.maven.artifact.repository.ArtifactRepository;
+
+/**
+ * Gets the preferred implementation of a repository query layer for the given repository.
+ *
+ * @author <a href="mailto:brett@apache.org">Brett Porter</a>
+ * @version $Id:RepositoryQueryLayerFactory.java 437105 2006-08-26 17:22:22 +1000 (Sat, 26 Aug 2006) brett $
+ */
+public interface RepositoryQueryLayerFactory
+{
+ String ROLE = RepositoryQueryLayerFactory.class.getName();
+
+ /**
+ * Create or obtain a query interface.
+ *
+ * @param repository the repository to query
+ * @return the obtained query layer
+ */
+ RepositoryQueryLayer createRepositoryQueryLayer( ArtifactRepository repository );
+}
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven</groupId>
<module>archiva-core</module>
<module>archiva-configuration</module>
<module>maven-meeper</module>
+ <module>archiva-repository-layer</module>
</modules>
<dependencies>
<dependency>
<artifactId>archiva-discoverer</artifactId>
<version>${pom.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.maven.archiva</groupId>
+ <artifactId>archiva-repository-layer</artifactId>
+ <version>${pom.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.maven.archiva</groupId>
<artifactId>archiva-indexer</artifactId>