From: Brett Porter Date: Tue, 5 Sep 2006 05:12:31 +0000 (+0000) Subject: [MRM-161] move the query layer to a separate module X-Git-Tag: archiva-0.9-alpha-1~611 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=d29cdf4ab1f77b962802f92f9d94c707fbb39037;p=archiva.git [MRM-161] move the query layer to a separate module git-svn-id: https://svn.apache.org/repos/asf/maven/archiva/trunk@440260 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/archiva-reports-standard/pom.xml b/archiva-reports-standard/pom.xml index 64df5f2d6..6a0bb7183 100755 --- a/archiva-reports-standard/pom.xml +++ b/archiva-reports-standard/pom.xml @@ -57,6 +57,10 @@ org.apache.maven.archiva archiva-utils + + org.apache.maven.archiva + archiva-repository-layer + org.apache.maven.archiva archiva-indexer diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/AbstractRepositoryQueryLayer.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/AbstractRepositoryQueryLayer.java deleted file mode 100644 index 8d9bc6e3e..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/AbstractRepositoryQueryLayer.java +++ /dev/null @@ -1,106 +0,0 @@ -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; - } -} diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/BadMetadataReportProcessor.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/BadMetadataReportProcessor.java index bb3869ad2..733524002 100644 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/BadMetadataReportProcessor.java +++ b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/BadMetadataReportProcessor.java @@ -16,6 +16,8 @@ package org.apache.maven.archiva.reporting; * 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; diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/Cache.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/Cache.java deleted file mode 100644 index 2559cf2e2..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/Cache.java +++ /dev/null @@ -1,221 +0,0 @@ -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(); - } - } - } - } - -} diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/CachedRepositoryQueryLayer.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/CachedRepositoryQueryLayer.java deleted file mode 100644 index 7b455899a..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/CachedRepositoryQueryLayer.java +++ /dev/null @@ -1,99 +0,0 @@ -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; - } -} diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultArtifactReportProcessor.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultArtifactReportProcessor.java index 040113af6..22e220a66 100644 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultArtifactReportProcessor.java +++ b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultArtifactReportProcessor.java @@ -16,6 +16,7 @@ package org.apache.maven.archiva.reporting; * 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; diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultRepositoryQueryLayer.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultRepositoryQueryLayer.java deleted file mode 100644 index 4b000fbe6..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultRepositoryQueryLayer.java +++ /dev/null @@ -1,31 +0,0 @@ -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; - } -} diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultRepositoryQueryLayerFactory.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultRepositoryQueryLayerFactory.java deleted file mode 100644 index ec607b6f1..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/DefaultRepositoryQueryLayerFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -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 Brett Porter - * @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 ); - } -} diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayer.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayer.java deleted file mode 100644 index bde683ed9..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayer.java +++ /dev/null @@ -1,40 +0,0 @@ -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; -} diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayerException.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayerException.java deleted file mode 100644 index a95415398..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayerException.java +++ /dev/null @@ -1,34 +0,0 @@ -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 ); - } -} diff --git a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayerFactory.java b/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayerFactory.java deleted file mode 100644 index e69527b5e..000000000 --- a/archiva-reports-standard/src/main/java/org/apache/maven/archiva/reporting/RepositoryQueryLayerFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -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 Brett Porter - * @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 ); -} diff --git a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/AbstractRepositoryQueryLayerTestCase.java b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/AbstractRepositoryQueryLayerTestCase.java index 0774095d5..52fd4efc5 100644 --- a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/AbstractRepositoryQueryLayerTestCase.java +++ b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/AbstractRepositoryQueryLayerTestCase.java @@ -16,6 +16,8 @@ package org.apache.maven.archiva.reporting; * 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; diff --git a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CacheTest.java b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CacheTest.java index 123e92f30..65d6f8109 100644 --- a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CacheTest.java +++ b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CacheTest.java @@ -17,6 +17,7 @@ package org.apache.maven.archiva.reporting; */ import junit.framework.TestCase; +import org.apache.maven.archiva.layer.Cache; /** * diff --git a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CachedRepositoryQueryLayerTest.java b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CachedRepositoryQueryLayerTest.java index 44e3d3108..bba92c722 100644 --- a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CachedRepositoryQueryLayerTest.java +++ b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/CachedRepositoryQueryLayerTest.java @@ -1,5 +1,7 @@ package org.apache.maven.archiva.reporting; +import org.apache.maven.archiva.layer.CachedRepositoryQueryLayer; + /* * Copyright 2005-2006 The Apache Software Foundation. * diff --git a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/MockRepositoryQueryLayer.java b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/MockRepositoryQueryLayer.java index 6657a29a0..e1aa69ac2 100644 --- a/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/MockRepositoryQueryLayer.java +++ b/archiva-reports-standard/src/test/java/org/apache/maven/archiva/reporting/MockRepositoryQueryLayer.java @@ -16,6 +16,7 @@ package org.apache.maven.archiva.reporting; * 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; @@ -25,7 +26,7 @@ import java.util.Iterator; import java.util.List; /** - * + * */ public class MockRepositoryQueryLayer implements RepositoryQueryLayer diff --git a/archiva-repository-layer/pom.xml b/archiva-repository-layer/pom.xml new file mode 100644 index 000000000..3b177c22e --- /dev/null +++ b/archiva-repository-layer/pom.xml @@ -0,0 +1,43 @@ + + + + + + + archiva + org.apache.maven.archiva + 1.0-SNAPSHOT + + 4.0.0 + org.apache.maven.archiva + archiva-repository-layer + Archiva Repository Interface Layer + + + org.apache.maven + maven-artifact + + + org.apache.maven + maven-artifact-manager + + + org.apache.maven + maven-repository-metadata + + + diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/AbstractRepositoryQueryLayer.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/AbstractRepositoryQueryLayer.java new file mode 100644 index 000000000..60b0e5bb0 --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/AbstractRepositoryQueryLayer.java @@ -0,0 +1,106 @@ +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; + } +} diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/Cache.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/Cache.java new file mode 100644 index 000000000..fc68f9ca6 --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/Cache.java @@ -0,0 +1,221 @@ +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(); + } + } + } + } + +} diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/CachedRepositoryQueryLayer.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/CachedRepositoryQueryLayer.java new file mode 100644 index 000000000..91f9c5ff9 --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/CachedRepositoryQueryLayer.java @@ -0,0 +1,99 @@ +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; + } +} diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/DefaultRepositoryQueryLayer.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/DefaultRepositoryQueryLayer.java new file mode 100644 index 000000000..582d5f377 --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/DefaultRepositoryQueryLayer.java @@ -0,0 +1,31 @@ +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; + } +} diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/DefaultRepositoryQueryLayerFactory.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/DefaultRepositoryQueryLayerFactory.java new file mode 100644 index 000000000..ebfcd18cf --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/DefaultRepositoryQueryLayerFactory.java @@ -0,0 +1,35 @@ +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 Brett Porter + * @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 ); + } +} diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayer.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayer.java new file mode 100644 index 000000000..93c57ef1f --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayer.java @@ -0,0 +1,37 @@ +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; +} diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayerException.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayerException.java new file mode 100644 index 000000000..772bf4666 --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayerException.java @@ -0,0 +1,34 @@ +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 ); + } +} diff --git a/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayerFactory.java b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayerFactory.java new file mode 100644 index 000000000..61142e937 --- /dev/null +++ b/archiva-repository-layer/src/main/java/org/apache/maven/archiva/layer/RepositoryQueryLayerFactory.java @@ -0,0 +1,38 @@ +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 Brett Porter + * @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 ); +} diff --git a/pom.xml b/pom.xml index a81e96b20..6b02a1c8d 100644 --- a/pom.xml +++ b/pom.xml @@ -14,7 +14,8 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License. --> - + 4.0.0 org.apache.maven @@ -126,6 +127,7 @@ archiva-core archiva-configuration maven-meeper + archiva-repository-layer @@ -212,6 +214,11 @@ archiva-discoverer ${pom.version} + + org.apache.maven.archiva + archiva-repository-layer + ${pom.version} + org.apache.maven.archiva archiva-indexer