Author: jdcasey
Date: Wed Nov 14 20:57:44 2007
New Revision: 595206

URL: http://svn.apache.org/viewvc?rev=595206&view=rev
Log:
Adding an aspect for caching resolution results. It's not enabled yet, since it 
has bugs and needs a little work.

Added:
    maven/artifact/trunk/src/main/aspect/
    maven/artifact/trunk/src/main/aspect/org/
    maven/artifact/trunk/src/main/aspect/org/apache/
    maven/artifact/trunk/src/main/aspect/org/apache/maven/
    maven/artifact/trunk/src/main/aspect/org/apache/maven/artifact/
    maven/artifact/trunk/src/main/aspect/org/apache/maven/artifact/aspect/
    
maven/artifact/trunk/src/main/aspect/org/apache/maven/artifact/aspect/ResolverCacheAspect.aj
    
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
   (with props)
Modified:
    maven/artifact/trunk/pom.xml
    
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java

Modified: maven/artifact/trunk/pom.xml
URL: 
http://svn.apache.org/viewvc/maven/artifact/trunk/pom.xml?rev=595206&r1=595205&r2=595206&view=diff
==============================================================================
--- maven/artifact/trunk/pom.xml (original)
+++ maven/artifact/trunk/pom.xml Wed Nov 14 20:57:44 2007
@@ -50,6 +50,11 @@
       <version>1.0-beta-2</version>
     </dependency>
     <dependency>
+      <groupId>aspectj</groupId>
+      <artifactId>aspectjrt</artifactId>
+      <version>1.5.3</version>
+    </dependency>
+    <dependency>
       <groupId>org.apache.maven.wagon</groupId>
       <artifactId>wagon-file</artifactId>
       <version>1.0-beta-2</version>
@@ -106,6 +111,25 @@
           <source>1.5</source>
         </configuration>
       </plugin>
+      <!--
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>aspectj-maven-plugin</artifactId>
+        <version>1.0-beta-2</version>
+        <executions>
+          <execution>
+            <id>compile</id>
+            <goals>
+              <goal>compile</goal>
+            </goals>
+            <configuration>
+              <source>1.5</source>
+              <target>1.5</target>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      -->
       <plugin>
         <groupId>org.codehaus.plexus</groupId>
         <artifactId>plexus-maven-plugin</artifactId>

Added: 
maven/artifact/trunk/src/main/aspect/org/apache/maven/artifact/aspect/ResolverCacheAspect.aj
URL: 
http://svn.apache.org/viewvc/maven/artifact/trunk/src/main/aspect/org/apache/maven/artifact/aspect/ResolverCacheAspect.aj?rev=595206&view=auto
==============================================================================
--- 
maven/artifact/trunk/src/main/aspect/org/apache/maven/artifact/aspect/ResolverCacheAspect.aj
 (added)
+++ 
maven/artifact/trunk/src/main/aspect/org/apache/maven/artifact/aspect/ResolverCacheAspect.aj
 Wed Nov 14 20:57:44 2007
@@ -0,0 +1,212 @@
+package org.apache.maven.artifact.aspect;
+
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.context.Context;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionException;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
+import org.apache.maven.artifact.resolver.ArtifactResolver;
+import org.apache.maven.artifact.resolver.DefaultArtifactResolver;
+import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.artifact.resolver.conflict.ConflictResolver;
+
+public privileged aspect ResolverCacheAspect
+{
+
+    declare parents: DefaultArtifactResolver implements Contextualizable;
+
+    private Map<String, Artifact> 
DefaultArtifactResolver.cachedSingleResolutions =
+        new HashMap<String, Artifact>();
+
+    private Map<String, ArtifactResolutionResult> 
DefaultArtifactResolver.cachedResolutionResults =
+        new HashMap<String, ArtifactResolutionResult>();
+
+    private PlexusContainer DefaultArtifactResolver.container;
+    private Logger DefaultArtifactResolver.logger;
+
+    // NOTE: We implement advice on this method rather than setting the 
container instance
+    // directly, so we can still recover the container even if the resolver 
implementation
+    // happens to override the method.
+    public void DefaultArtifactResolver.contextualize( Context context ) 
throws ContextException
+    {
+        if ( container == null )
+        {
+            container = (PlexusContainer) context.get( 
PlexusConstants.PLEXUS_KEY );
+            logger = container.getLoggerManager().getLoggerForComponent( 
ArtifactResolver.ROLE );
+
+            logger.debug( "DefaultArtifactResolver caching aspect captured 
PlexusContainer instance." );
+        }
+    }
+
+    private pointcut deprecatedSingleResolveCall( Artifact artifact, 
DefaultArtifactResolver resolver ):
+        execution( void DefaultArtifactResolver+.resolve( Artifact, .. ) )
+        && args( artifact, .. )
+        && this( resolver );
+
+    void around( Artifact artifact, DefaultArtifactResolver resolver )
+        throws ArtifactResolutionException, ArtifactNotFoundException:
+        deprecatedSingleResolveCall( artifact, resolver )
+    {
+        System.out.println( "Cache check for: " + artifact + " using resolver: 
" + resolver + " (has logger? " + ( resolver != null && resolver.logger != null 
) + ")" );
+
+        String key = createCacheKey( null, (Set<Artifact>) 
Collections.singleton( artifact ), null, null );
+        resolver.logger.debug( "Checking artifact resolution cache for: " + 
key );
+
+        Artifact cached = resolver.cachedSingleResolutions.get( key );
+        if ( cached != null )
+        {
+            resolver.logger.debug( "Using cached copy of: " + key );
+            copyFromCached( artifact, cached );
+
+            return;
+        }
+
+        proceed( artifact, resolver );
+
+        resolver.logger.debug( "Caching: " + key );
+        resolver.cachedSingleResolutions.put( key, artifact );
+    }
+
+    private pointcut deprecatedTransitiveResolveCall( Set artifacts, Artifact 
originatingArtifact, DefaultArtifactResolver resolver ):
+        execution( ArtifactResolutionResult 
DefaultArtifactResolver+.resolveTransitively( Set, Artifact, .. ) )
+        && args( artifacts, originatingArtifact, .. )
+        && this( resolver );
+
+    @SuppressWarnings("unchecked")
+    ArtifactResolutionResult around( Set artifacts, Artifact 
originatingArtifact, DefaultArtifactResolver resolver )
+        throws ArtifactResolutionException, ArtifactNotFoundException:
+        deprecatedTransitiveResolveCall( artifacts, originatingArtifact, 
resolver )
+    {
+        ArtifactFilter filter = null;
+        for ( Object arg : thisJoinPoint.getArgs() )
+        {
+            if ( arg instanceof ArtifactFilter )
+            {
+                filter = (ArtifactFilter) arg;
+                break;
+            }
+        }
+
+        String key = createCacheKey( originatingArtifact, artifacts, null, 
filter );
+        resolver.logger.debug( "Checking artifact resolution cache for: " + 
key );
+
+        ArtifactResolutionResult cached = 
resolver.cachedResolutionResults.get( key );
+        if ( cached != null )
+        {
+            resolver.logger.debug( "Using cached copy of: " + key );
+            return cached;
+        }
+
+        cached = proceed( artifacts, originatingArtifact, resolver );
+
+        resolver.logger.debug( "Caching: " + key );
+        resolver.cachedResolutionResults.put( key, cached );
+
+        return cached;
+    }
+
+    private pointcut resolveCallWithRequest( ArtifactResolutionRequest 
request, DefaultArtifactResolver resolver ):
+        execution( ArtifactResolutionResult DefaultArtifactResolver+.resolve( 
ArtifactResolutionRequest ) )
+        && args( request )
+        && this( resolver );
+
+    @SuppressWarnings("unchecked")
+    ArtifactResolutionResult around( ArtifactResolutionRequest request, 
DefaultArtifactResolver resolver ):
+        resolveCallWithRequest( request, resolver )
+    {
+        String key = createCacheKey( request.getArtifact(), 
request.getArtifactDependencies(),
+                                     request.getConflictResolvers(), 
request.getFilter() );
+
+        resolver.logger.debug( "Checking artifact resolution cache for: " + 
key );
+
+        ArtifactResolutionResult cached = 
resolver.cachedResolutionResults.get( key );
+        if ( cached != null )
+        {
+            resolver.logger.debug( "Using cached copy of: " + key );
+            return cached;
+        }
+
+        cached = proceed( request, resolver );
+
+        resolver.logger.debug( "Caching: " + key );
+        resolver.cachedResolutionResults.put( key, cached );
+
+        return cached;
+    }
+
+    private void copyFromCached( Artifact artifact, Artifact cached )
+    {
+        artifact.setFile( cached.getFile() );
+        artifact.setResolved( cached.isResolved() );
+        artifact.setRepository( cached.getRepository() );
+        artifact.setDownloadUrl( cached.getDownloadUrl() );
+        artifact.setVersion( cached.getVersion() );
+
+        artifact.setAvailableVersions( cached.getAvailableVersions() );
+        artifact.setBaseVersion( cached.getBaseVersion() );
+        artifact.setDependencyTrail( cached.getDependencyTrail() );
+    }
+
+    private String createCacheKey( Artifact originatingArtifact, Set<Artifact> 
artifacts, List<ConflictResolver> conflictResolvers, ArtifactFilter filter )
+    {
+        // NOTE: artifact sets in different orders can produce different 
results in transitive resolution.
+        // Therefore, DO NOT sort this alphabetically first...preserve the set 
ordering, if there is any.
+        // String[] ids = new String[artifacts.size()];
+        // int i=0;
+        // for ( Artifact artifact : artifacts )
+        // {
+        //     ids[i] = artifact.getId();
+        //     i++;
+        // }
+        //
+        // Arrays.sort( ids );
+
+        // TODO: Review. This will be ugly, and may not be great on the 
memory, but it should work for now.
+        StringBuilder sb = new StringBuilder();
+
+        if ( originatingArtifact != null )
+        {
+            sb.append( originatingArtifact.getId() );
+            sb.append( ':' );
+        }
+
+        for ( Artifact artifact : artifacts )
+        {
+            sb.append( artifact.getId() );
+            sb.append( ':' );
+        }
+
+        if ( conflictResolvers != null )
+        {
+            for ( ConflictResolver conflictResolver : conflictResolvers )
+            {
+                sb.append( conflictResolver.hashCode() );
+                sb.append( ':' );
+            }
+        }
+
+        if ( filter != null )
+        {
+            sb.append( filter.hashCode() );
+            sb.append( ':' );
+        }
+
+        sb.setLength( sb.length() - 1 );
+
+        return sb.toString();
+    }
+
+}

Modified: 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java
URL: 
http://svn.apache.org/viewvc/maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java?rev=595206&r1=595205&r2=595206&view=diff
==============================================================================
--- 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java
 (original)
+++ 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java
 Wed Nov 14 20:57:44 2007
@@ -51,6 +51,7 @@
 
     private Artifact projectArtifact;
 
+    @Override
     protected void setUp()
         throws Exception
     {
@@ -61,6 +62,7 @@
         projectArtifact = createLocalArtifact( "project", "3.0" );
     }
 
+    @Override
     protected String component()
     {
         return "resolver";
@@ -87,6 +89,7 @@
         assertLocalArtifactPresent( b );
     }
 
+    @Override
     protected Artifact createArtifact( String groupId, String artifactId, 
String version, String type )
         throws Exception
     {

Added: 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
URL: 
http://svn.apache.org/viewvc/maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java?rev=595206&view=auto
==============================================================================
--- 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
 (added)
+++ 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
 Wed Nov 14 20:57:44 2007
@@ -0,0 +1,15 @@
+package org.apache.maven.artifact.resolver;
+
+import org.codehaus.plexus.PlexusTestCase;
+
+public class DefaultArtifactResolverTest
+    extends PlexusTestCase
+{
+
+    public void testLookup()
+        throws Exception
+    {
+        ArtifactResolver resolver = (ArtifactResolver) lookup( 
ArtifactResolver.ROLE, "default" );
+    }
+
+}

Propchange: 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
maven/artifact/trunk/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactResolverTest.java
------------------------------------------------------------------------------
    svn:keywords = "Author Date Id Revision"


Reply via email to