You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2011/05/24 05:33:07 UTC
svn commit: r1126854 [1/2] - in
/maven/maven-3/branches/mirror-group-routing: ./ apache-maven/
maven-aether-provider/src/main/java/org/apache/maven/repository/internal/
maven-compat/ maven-core/ maven-core/src/main/java/org/apache/maven/
maven-core/src...
Author: jdcasey
Date: Tue May 24 03:33:06 2011
New Revision: 1126854
URL: http://svn.apache.org/viewvc?rev=1126854&view=rev
Log:
making a route-m aware variant of the aether-connector-wagon project. Adding code to init the ArtifactRouter in the session data
Added:
maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/
maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/mirror/
maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/mirror/RoutingMirrorSelector.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/pom.xml (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonConfigurator.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonProvider.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingConnectorWrapper.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingWagonRepositoryConnectorFactory.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonConfigurator.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonProvider.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonRepositoryConnector.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonTransferListenerAdapter.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/java/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/java/org/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/java/org/apache/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/java/org/apache/maven/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/java/org/apache/maven/router/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/java/org/apache/maven/router/repository/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/java/org/apache/maven/router/repository/TestSuiteHttpWagon.java (with props)
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/resources/
maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/test/resources/logback-test.xml (with props)
Removed:
maven/maven-3/branches/mirror-group-routing/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RoutingRemoteRepositoryManager.java
maven/maven-3/branches/mirror-group-routing/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RoutingRepositoryConnector.java
maven/maven-3/branches/mirror-group-routing/maven-aether-provider/src/main/java/org/apache/maven/repository/internal/RoutingRepositoryConnectorFactory.java
maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/repository/mirror/RoutingMirrorSelector.java
Modified:
maven/maven-3/branches/mirror-group-routing/apache-maven/pom.xml
maven/maven-3/branches/mirror-group-routing/maven-compat/pom.xml
maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml
maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
maven/maven-3/branches/mirror-group-routing/maven-routem-api/src/main/java/org/apache/maven/artifact/router/ArtifactRouter.java
maven/maven-3/branches/mirror-group-routing/maven-routem-api/src/main/java/org/apache/maven/artifact/router/GroupRoute.java
maven/maven-3/branches/mirror-group-routing/maven-routem-api/src/main/java/org/apache/maven/artifact/router/MirrorRoute.java
maven/maven-3/branches/mirror-group-routing/pom.xml
maven/maven-3/branches/mirror-group-routing/pom.xml.orig
Modified: maven/maven-3/branches/mirror-group-routing/apache-maven/pom.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/apache-maven/pom.xml?rev=1126854&r1=1126853&r2=1126854&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/apache-maven/pom.xml (original)
+++ maven/maven-3/branches/mirror-group-routing/apache-maven/pom.xml Tue May 24 03:33:06 2011
@@ -60,8 +60,8 @@
<artifactId>wagon-file</artifactId>
</dependency>
<dependency>
- <groupId>org.sonatype.aether</groupId>
- <artifactId>aether-connector-wagon</artifactId>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-routem-aether-wagon-connector</artifactId>
</dependency>
</dependencies>
Modified: maven/maven-3/branches/mirror-group-routing/maven-compat/pom.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-compat/pom.xml?rev=1126854&r1=1126853&r2=1126854&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-compat/pom.xml (original)
+++ maven/maven-3/branches/mirror-group-routing/maven-compat/pom.xml Tue May 24 03:33:06 2011
@@ -70,9 +70,8 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.sonatype.aether</groupId>
- <artifactId>aether-connector-wagon</artifactId>
- <version>${aetherVersion}</version>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-routem-aether-wagon-connector</artifactId>
<scope>test</scope>
</dependency>
<dependency>
Modified: maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml?rev=1126854&r1=1126853&r2=1126854&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml (original)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/pom.xml Tue May 24 03:33:06 2011
@@ -64,17 +64,14 @@
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-impl</artifactId>
- <version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-api</artifactId>
- <version>${aetherVersion}</version>
</dependency>
<dependency>
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-util</artifactId>
- <version>${aetherVersion}</version>
</dependency>
<!-- Plexus -->
<dependency>
Modified: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/DefaultMaven.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/DefaultMaven.java?rev=1126854&r1=1126853&r2=1126854&view=diff
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/DefaultMaven.java (original)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/DefaultMaven.java Tue May 24 03:33:06 2011
@@ -33,6 +33,8 @@ import java.util.Properties;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
+import org.apache.maven.artifact.router.ArtifactRouter;
+import org.apache.maven.artifact.router.mirror.RoutingMirrorSelector;
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
import org.apache.maven.execution.DefaultMavenExecutionResult;
import org.apache.maven.execution.ExecutionEvent;
@@ -58,7 +60,6 @@ import org.apache.maven.project.ProjectB
import org.apache.maven.project.ProjectSorter;
import org.apache.maven.repository.DelegatingLocalArtifactRepository;
import org.apache.maven.repository.LocalRepositoryNotAccessibleException;
-import org.apache.maven.repository.mirror.RoutingMirrorSelector;
import org.apache.maven.settings.Mirror;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Server;
@@ -331,6 +332,7 @@ public class DefaultMaven
public RepositorySystemSession newRepositorySession( MavenExecutionRequest request )
{
DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
+ session.getData().set( ArtifactRouter.SESSION_KEY, request.getArtifactRouter() );
session.setCache( request.getRepositoryCache() );
Added: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/mirror/RoutingMirrorSelector.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/mirror/RoutingMirrorSelector.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/mirror/RoutingMirrorSelector.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/mirror/RoutingMirrorSelector.java Tue May 24 03:33:06 2011
@@ -0,0 +1,109 @@
+package org.apache.maven.artifact.router.mirror;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.router.MirrorRoute;
+import org.apache.maven.artifact.router.ArtifactRouter;
+import org.codehaus.plexus.logging.Logger;
+import org.sonatype.aether.repository.MirrorSelector;
+import org.sonatype.aether.repository.RemoteRepository;
+import org.sonatype.aether.util.repository.DefaultMirrorSelector;
+
+import java.util.Collections;
+
+public class RoutingMirrorSelector
+ implements MirrorSelector
+{
+
+ private final ArtifactRouter router;
+
+ private final DefaultMirrorSelector delegate = new DefaultMirrorSelector();
+
+ private final Logger logger;
+
+ public RoutingMirrorSelector( final ArtifactRouter router, final Logger logger )
+ {
+ this.router = router;
+ this.logger = logger;
+ }
+
+ public RemoteRepository getMirror( final RemoteRepository repository )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "AETHER-SELECT: " + repository.getUrl() );
+ }
+
+ RemoteRepository mirror = delegate.getMirror( repository );
+ if ( mirror != null )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "AETHER-SELECT using mirror from settings.xml." );
+ }
+
+ return mirror;
+ }
+
+ if ( mirror == null )
+ {
+ final String repoUrl = repository.getUrl();
+
+ final MirrorRoute route = router.getMirror( repoUrl );
+
+ if ( route != null )
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "\t==> " + route );
+ }
+
+ mirror = new RemoteRepository();
+
+ mirror.setRepositoryManager( false );
+ mirror.setId( route.getId() );
+ mirror.setUrl( route.getRouteUrl() );
+ mirror.setContentType( repository.getContentType() );
+ mirror.setPolicy( true, repository.getPolicy( true ) );
+ mirror.setPolicy( false, repository.getPolicy( false ) );
+
+ mirror.setMirroredRepositories( Collections.singletonList( repository ) );
+ }
+ else
+ {
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "AETHER-SELECT: no auto-mirror found." );
+ }
+ }
+ }
+
+ return mirror;
+ }
+
+ public RoutingMirrorSelector add( final String id, final String url, final String type,
+ final boolean repositoryManager, final String mirrorOfIds,
+ final String mirrorOfTypes )
+ {
+ delegate.add( id, url, type, repositoryManager, mirrorOfIds, mirrorOfTypes );
+ return this;
+ }
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-core/src/main/java/org/apache/maven/artifact/router/mirror/RoutingMirrorSelector.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/pom.xml
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/pom.xml?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/pom.xml (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/pom.xml Tue May 24 03:33:06 2011
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ ~ Copyright (c) 2010-2011 Sonatype, Inc.
+ ~ All rights reserved. This program and the accompanying materials
+ ~ are made available under the terms of the Eclipse Public License v1.0
+ ~ and Apache License v2.0 which accompanies this distribution.
+ ~ The Eclipse Public License is available at
+ ~ http://www.eclipse.org/legal/epl-v10.html
+ ~ The Apache License v2.0 is available at
+ ~ http://www.apache.org/licenses/LICENSE-2.0.html
+ ~ You may elect to redistribute this code under either of these licenses.
+-->
+
+<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/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven</artifactId>
+ <version>3.0.4-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>maven-routem-aether-wagon-connector</artifactId>
+
+ <name>Maven Route-M / Wagon Aether Connector</name>
+
+ <description>
+ A repository connector based on Maven Wagon that is Route-M aware.
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.sonatype.aether</groupId>
+ <artifactId>aether-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.aether</groupId>
+ <artifactId>aether-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.aether</groupId>
+ <artifactId>aether-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-provider-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-annotations</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-classworlds</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.aether</groupId>
+ <artifactId>aether-test-util</artifactId>
+ <version>${aetherVersion}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.wagon</groupId>
+ <artifactId>wagon-http-lightweight</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.http-testing-harness</groupId>
+ <artifactId>server-provider</artifactId>
+ <version>0.4.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.sonatype.sisu</groupId>
+ <artifactId>sisu-inject-plexus</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-routem-api</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-component-metadata</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonConfigurator.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonConfigurator.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonConfigurator.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonConfigurator.java Tue May 24 03:33:06 2011
@@ -0,0 +1,86 @@
+package org.apache.maven.router.repository;
+
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ * http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.configurator.AbstractComponentConfigurator;
+import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
+import org.codehaus.plexus.component.configurator.ConfigurationListener;
+import org.codehaus.plexus.component.configurator.converters.composite.ObjectWithFieldsConverter;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+/**
+ * A wagon configurator based on the Plexus component configuration framework.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = WagonConfigurator.class, hint = "plexus" )
+public class PlexusWagonConfigurator
+ implements WagonConfigurator
+{
+
+ @Requirement
+ private PlexusContainer container;
+
+ public void configure( Wagon wagon, Object configuration )
+ throws Exception
+ {
+ PlexusConfiguration config = null;
+ if ( configuration instanceof PlexusConfiguration )
+ {
+ config = (PlexusConfiguration) configuration;
+ }
+ else if ( configuration instanceof Xpp3Dom )
+ {
+ config = new XmlPlexusConfiguration( (Xpp3Dom) configuration );
+ }
+ else if ( configuration == null )
+ {
+ return;
+ }
+ else
+ {
+ throw new IllegalArgumentException( "Unexpected configuration type: " + configuration.getClass().getName() );
+ }
+
+ WagonComponentConfigurator configurator = new WagonComponentConfigurator();
+
+ configurator.configureComponent( wagon, config, container.getContainerRealm() );
+ }
+
+ static class WagonComponentConfigurator
+ extends AbstractComponentConfigurator
+ {
+
+ @Override
+ public void configureComponent( Object component, PlexusConfiguration configuration,
+ ExpressionEvaluator expressionEvaluator, ClassRealm containerRealm,
+ ConfigurationListener listener )
+ throws ComponentConfigurationException
+ {
+ ObjectWithFieldsConverter converter = new ObjectWithFieldsConverter();
+
+ converter.processConfiguration( converterLookup, component, containerRealm, configuration,
+ expressionEvaluator, listener );
+ }
+
+ }
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonConfigurator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonProvider.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonProvider.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonProvider.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonProvider.java Tue May 24 03:33:06 2011
@@ -0,0 +1,54 @@
+package org.apache.maven.router.repository;
+
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ * http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+/**
+ * A wagon provider backed by a Plexus container and the wagons registered with this container.
+ *
+ * @author Benjamin Bentmann
+ */
+@Component( role = WagonProvider.class, hint = "plexus" )
+public class PlexusWagonProvider
+ implements WagonProvider
+{
+
+ @Requirement
+ private PlexusContainer container;
+
+ public Wagon lookup( String roleHint )
+ throws Exception
+ {
+ return container.lookup( Wagon.class, roleHint );
+ }
+
+ public void release( Wagon wagon )
+ {
+ try
+ {
+ if ( wagon != null )
+ {
+ container.release( wagon );
+ }
+ }
+ catch ( Exception e )
+ {
+ // too bad
+ }
+ }
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/PlexusWagonProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingConnectorWrapper.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingConnectorWrapper.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingConnectorWrapper.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingConnectorWrapper.java Tue May 24 03:33:06 2011
@@ -0,0 +1,314 @@
+package org.apache.maven.router.repository;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.artifact.router.ArtifactRouter;
+import org.apache.maven.artifact.router.GroupRoute;
+import org.sonatype.aether.RepositorySystemSession;
+import org.sonatype.aether.RequestTrace;
+import org.sonatype.aether.repository.Authentication;
+import org.sonatype.aether.repository.Proxy;
+import org.sonatype.aether.repository.RemoteRepository;
+import org.sonatype.aether.spi.connector.ArtifactDownload;
+import org.sonatype.aether.spi.connector.ArtifactUpload;
+import org.sonatype.aether.spi.connector.MetadataDownload;
+import org.sonatype.aether.spi.connector.MetadataUpload;
+import org.sonatype.aether.spi.connector.RepositoryConnector;
+import org.sonatype.aether.spi.io.FileProcessor;
+import org.sonatype.aether.spi.log.Logger;
+import org.sonatype.aether.transfer.NoRepositoryConnectorException;
+import org.sonatype.aether.transfer.TransferEvent;
+import org.sonatype.aether.util.listener.DefaultTransferEvent;
+import org.sonatype.aether.util.listener.DefaultTransferResource;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * {@link RepositoryConnector} implementation that resolves the proper repository URL using Route-M
+ * routing information (groupId -> canonical URL -> mirror URL), then delegates transfers to
+ * the appropriate <b>real</b> {@link WagonRepositoryConnector} for each artifact or metadata.
+ * <br/>
+ * <b>NOTE:</b> Artifact/metadata transfers sharing a groupId are collected and sent together to the appropriate
+ * {@link WagonRepositoryConnector} when get(..) or put(..) is called.
+ *
+ * @author John Casey
+ */
+class RoutingConnectorWrapper
+ implements RepositoryConnector
+{
+
+ private static final String OPEN_CONNECTORS_KEY = RoutingConnectorWrapper.class.getName() + "#openConnectors";
+
+ private static final String PUT_CONNECTOR_KEY = RoutingConnectorWrapper.class.getName() + "#putConnector";
+
+ private final ArtifactRouter router;
+
+ private final RepositorySystemSession session;
+
+ private final RemoteRepository baseRepository;
+
+ private final WagonProvider wagonProvider;
+
+ private final WagonConfigurator wagonConfigurator;
+
+ private final FileProcessor fileProcessor;
+
+ private final Logger logger;
+
+ public RoutingConnectorWrapper( RemoteRepository baseRepository, RepositorySystemSession session,
+ WagonProvider wagonProvider, WagonConfigurator wagonConfigurator,
+ FileProcessor fileProcessor, Logger logger )
+ {
+ this.baseRepository = baseRepository;
+ this.wagonProvider = wagonProvider;
+ this.wagonConfigurator = wagonConfigurator;
+ this.fileProcessor = fileProcessor;
+ this.logger = logger;
+
+ ArtifactRouter router = (ArtifactRouter) session.getData().get( ArtifactRouter.SESSION_KEY );
+ if ( router == null )
+ {
+ logger.debug( "Creating empty ArtifactRouter, since none has been initialized." );
+ router = new ArtifactRouter();
+ session.getData().set( ArtifactRouter.SESSION_KEY, router );
+ }
+
+ this.router = router;
+
+ this.session = session;
+
+ if ( getOpenConnectors() == null )
+ {
+ setOpenConnectors( new HashMap<GroupRoute, RepositoryConnector>() );
+ }
+ }
+
+ public synchronized void get( Collection<? extends ArtifactDownload> artifactDownloads,
+ Collection<? extends MetadataDownload> metadataDownloads )
+ {
+ Map<GroupRoute, Set<ArtifactDownload>> artifactDownloadsByGroup = new HashMap<GroupRoute, Set<ArtifactDownload>>();
+ Map<GroupRoute, Set<MetadataDownload>> metadataDownloadsByGroup = new HashMap<GroupRoute, Set<MetadataDownload>>();
+
+ if ( artifactDownloads != null )
+ {
+ for ( ArtifactDownload artifactDownload : artifactDownloads )
+ {
+ GroupRoute route = router.getGroup( artifactDownload.getArtifact().getGroupId() );
+ Set<ArtifactDownload> set = artifactDownloadsByGroup.get( route );
+ if ( set == null )
+ {
+ set = new LinkedHashSet<ArtifactDownload>();
+ artifactDownloadsByGroup.put( route, set );
+ }
+
+ set.add( artifactDownload );
+ initConnector( route, "Artifact: " + artifactDownload.getArtifact().toString(), artifactDownload.getFile(), artifactDownload.getTrace() );
+ }
+ }
+
+ if ( metadataDownloads != null )
+ {
+ for ( MetadataDownload metadataDownload : metadataDownloads )
+ {
+ GroupRoute route = router.getGroup( metadataDownload.getMetadata().getGroupId() );
+ Set<MetadataDownload> set = metadataDownloadsByGroup.get( route );
+ if ( set == null )
+ {
+ set = new LinkedHashSet<MetadataDownload>();
+ metadataDownloadsByGroup.put( route, set );
+ }
+
+ set.add( metadataDownload );
+ initConnector( route, "Metadata: " + metadataDownload.getMetadata().toString(), metadataDownload.getFile(), metadataDownload.getTrace() );
+ }
+ }
+
+ Map<GroupRoute, RepositoryConnector> connectors = getOpenConnectors();
+ for ( Map.Entry<GroupRoute, RepositoryConnector> entry : connectors.entrySet() )
+ {
+ GroupRoute route = entry.getKey();
+ RepositoryConnector connector = entry.getValue();
+ Set<ArtifactDownload> artifacts = artifactDownloadsByGroup.get( route );
+ Set<MetadataDownload> metadatas = metadataDownloadsByGroup.get( route );
+
+ if ( ( artifacts == null || artifacts.isEmpty() ) && ( metadatas == null || metadatas.isEmpty() ) )
+ {
+ continue;
+ }
+
+ connector.get( artifacts, metadatas );
+ }
+ }
+
+ public synchronized void put( Collection<? extends ArtifactUpload> artifactUploads,
+ Collection<? extends MetadataUpload> metadataUploads )
+ {
+ try
+ {
+ WagonRepositoryConnector connector = getPutConnector( true );
+ connector.put( artifactUploads, metadataUploads );
+ }
+ catch ( NoRepositoryConnectorException e )
+ {
+ logger.warn( "Cannot find Wagon for: " + baseRepository.getUrl(), e );
+ if ( session.getTransferListener() != null )
+ {
+ DefaultTransferEvent event = new DefaultTransferEvent();
+
+ String name =
+ ( artifactUploads == null ? 0 : artifactUploads.size() ) + " artifacts / "
+ + ( metadataUploads == null ? 0 : metadataUploads.size() ) + " metadata";
+
+ RequestTrace trace = null;
+ if ( artifactUploads != null )
+ {
+ for ( ArtifactUpload artifactUpload : artifactUploads )
+ {
+ trace = artifactUpload.getTrace();
+ break;
+ }
+ }
+
+ if ( trace == null && metadataUploads != null )
+ {
+ for ( MetadataUpload metadataUpload : metadataUploads )
+ {
+ trace = metadataUpload.getTrace();
+ break;
+ }
+ }
+
+ event.setResource( new DefaultTransferResource( baseRepository.getUrl(), name, null, trace ) );
+ event.setRequestType( TransferEvent.RequestType.GET );
+ event.setType( TransferEvent.EventType.FAILED );
+ event.setException( e );
+
+ session.getTransferListener().transferFailed( event );
+ }
+ }
+ }
+
+ public synchronized void close()
+ {
+ Map<GroupRoute, RepositoryConnector> openConnectors = getOpenConnectors();
+ for ( RepositoryConnector connector : openConnectors.values() )
+ {
+ connector.close();
+ }
+
+ setOpenConnectors( null );
+
+ try
+ {
+ WagonRepositoryConnector putConnector = getPutConnector( false );
+ if ( putConnector != null )
+ {
+ putConnector.close();
+ session.getData().set( PUT_CONNECTOR_KEY, null );
+ }
+ }
+ catch ( NoRepositoryConnectorException e )
+ {
+ }
+ }
+
+ private WagonRepositoryConnector getPutConnector( boolean create )
+ throws NoRepositoryConnectorException
+ {
+ WagonRepositoryConnector putConnector = (WagonRepositoryConnector) session.getData().get( PUT_CONNECTOR_KEY );
+ if ( create && putConnector == null )
+ {
+ putConnector = new WagonRepositoryConnector( wagonProvider, wagonConfigurator, baseRepository, session, fileProcessor, logger );
+ session.getData().set( PUT_CONNECTOR_KEY, putConnector );
+ }
+
+ return putConnector;
+ }
+
+ private void initConnector( GroupRoute route, String name, File file, RequestTrace trace )
+ {
+ Map<GroupRoute, RepositoryConnector> connectors = getOpenConnectors();
+ if ( !connectors.containsKey( route ) )
+ {
+ RemoteRepository repo;
+ if ( route == GroupRoute.DEFAULT )
+ {
+ repo = baseRepository;
+ }
+ else
+ {
+ repo = new RemoteRepository( baseRepository );
+ repo.setId( baseRepository.getId() );
+ repo.setUrl( route.getCanonicalUrl() );
+
+ RemoteRepository mirroredRepo = session.getMirrorSelector().getMirror( repo );
+ if ( mirroredRepo != null )
+ {
+ repo = mirroredRepo;
+ }
+
+ Authentication auth = session.getAuthenticationSelector().getAuthentication( repo );
+ repo.setAuthentication( auth );
+
+ Proxy proxy = session.getProxySelector().getProxy( repo );
+ repo.setProxy( proxy );
+ }
+
+ RepositoryConnector connector;
+ try
+ {
+ connector = new WagonRepositoryConnector( wagonProvider, wagonConfigurator, repo, session, fileProcessor,
+ logger );
+ connectors.put( route, connector );
+ }
+ catch ( NoRepositoryConnectorException e )
+ {
+ logger.warn( "Cannot find Wagon for: " + repo.getUrl(), e );
+ if ( session.getTransferListener() != null )
+ {
+ DefaultTransferEvent event = new DefaultTransferEvent();
+ event.setResource( new DefaultTransferResource( repo.getUrl(), name, file, trace ) );
+ event.setRequestType( TransferEvent.RequestType.GET );
+ event.setType( TransferEvent.EventType.FAILED );
+ event.setException( e );
+
+ session.getTransferListener().transferFailed( event );
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private Map<GroupRoute, RepositoryConnector> getOpenConnectors()
+ {
+ return (Map<GroupRoute, RepositoryConnector>) session.getData().get( OPEN_CONNECTORS_KEY );
+ }
+
+ private void setOpenConnectors( Map<GroupRoute, RepositoryConnector> connectors )
+ {
+ session.getData().set( OPEN_CONNECTORS_KEY, connectors );
+ }
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingConnectorWrapper.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingWagonRepositoryConnectorFactory.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingWagonRepositoryConnectorFactory.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingWagonRepositoryConnectorFactory.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingWagonRepositoryConnectorFactory.java Tue May 24 03:33:06 2011
@@ -0,0 +1,151 @@
+package org.apache.maven.router.repository;
+
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ * http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.sonatype.aether.RepositorySystemSession;
+import org.sonatype.aether.repository.RemoteRepository;
+import org.sonatype.aether.spi.connector.RepositoryConnector;
+import org.sonatype.aether.spi.connector.RepositoryConnectorFactory;
+import org.sonatype.aether.spi.io.FileProcessor;
+import org.sonatype.aether.spi.locator.Service;
+import org.sonatype.aether.spi.locator.ServiceLocator;
+import org.sonatype.aether.spi.log.Logger;
+import org.sonatype.aether.spi.log.NullLogger;
+import org.sonatype.aether.transfer.NoRepositoryConnectorException;
+
+/**
+ * A repository connector factory that uses Maven Wagon for the transfers.
+ * NOTE: This variant of aether-connector-wagon is Route-M (artifact routing) aware.
+ *
+ * @author Benjamin Bentmann
+ * @author John Casey
+ */
+@Component( role = RepositoryConnectorFactory.class, hint = "wagon" )
+public class RoutingWagonRepositoryConnectorFactory
+ implements RepositoryConnectorFactory, Service
+{
+
+ @Requirement
+ private Logger logger = NullLogger.INSTANCE;
+
+ @Requirement
+ private FileProcessor fileProcessor;
+
+ @Requirement
+ private WagonProvider wagonProvider;
+
+ @Requirement
+ private WagonConfigurator wagonConfigurator;
+
+ private int priority = Integer.MIN_VALUE;
+
+ public RoutingWagonRepositoryConnectorFactory()
+ {
+ // enables default constructor
+ }
+
+ public RoutingWagonRepositoryConnectorFactory( Logger logger, FileProcessor fileProcessor, WagonProvider wagonProvider,
+ WagonConfigurator wagonConfigurator )
+ {
+ setLogger( logger );
+ setFileProcessor( fileProcessor );
+ setWagonProvider( wagonProvider );
+ setWagonConfigurator( wagonConfigurator );
+ }
+
+ public void initService( ServiceLocator locator )
+ {
+ setLogger( locator.getService( Logger.class ) );
+ setFileProcessor( locator.getService( FileProcessor.class ) );
+ setWagonProvider( locator.getService( WagonProvider.class ) );
+ setWagonConfigurator( locator.getService( WagonConfigurator.class ) );
+ }
+
+ /**
+ * Sets the logger to use for this component.
+ *
+ * @param logger The logger to use, may be {@code null} to disable logging.
+ * @return This component for chaining, never {@code null}.
+ */
+ public RoutingWagonRepositoryConnectorFactory setLogger( Logger logger )
+ {
+ this.logger = ( logger != null ) ? logger : NullLogger.INSTANCE;
+ return this;
+ }
+
+ /**
+ * Sets the file processor to use for this component.
+ *
+ * @param fileProcessor The file processor to use, must not be {@code null}.
+ * @return This component for chaining, never {@code null}.
+ */
+ public RoutingWagonRepositoryConnectorFactory setFileProcessor( FileProcessor fileProcessor )
+ {
+ if ( fileProcessor == null )
+ {
+ throw new IllegalArgumentException( "file processor has not been specified" );
+ }
+ this.fileProcessor = fileProcessor;
+ return this;
+ }
+
+ /**
+ * Sets the wagon provider to use to acquire and release wagon instances.
+ *
+ * @param wagonProvider The wagon provider to use, may be {@code null}.
+ * @return This factory for chaining, never {@code null}.
+ */
+ public RoutingWagonRepositoryConnectorFactory setWagonProvider( WagonProvider wagonProvider )
+ {
+ this.wagonProvider = wagonProvider;
+ return this;
+ }
+
+ /**
+ * Sets the wagon configurator to use to apply provider-specific configuration to wagon instances.
+ *
+ * @param wagonConfigurator The wagon configurator to use, may be {@code null}.
+ * @return This factory for chaining, never {@code null}.
+ */
+ public RoutingWagonRepositoryConnectorFactory setWagonConfigurator( WagonConfigurator wagonConfigurator )
+ {
+ this.wagonConfigurator = wagonConfigurator;
+ return this;
+ }
+
+ public int getPriority()
+ {
+ return priority;
+ }
+
+ /**
+ * Sets the priority of this component.
+ *
+ * @param priority The priority.
+ * @return This component for chaining, never {@code null}.
+ */
+ public RoutingWagonRepositoryConnectorFactory setPriority( int priority )
+ {
+ this.priority = priority;
+ return this;
+ }
+
+ public RepositoryConnector newInstance( RepositorySystemSession session, RemoteRepository repository )
+ throws NoRepositoryConnectorException
+ {
+ return new RoutingConnectorWrapper( repository, session, wagonProvider, wagonConfigurator, fileProcessor, logger );
+ }
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/RoutingWagonRepositoryConnectorFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonConfigurator.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonConfigurator.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonConfigurator.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonConfigurator.java Tue May 24 03:33:06 2011
@@ -0,0 +1,35 @@
+package org.apache.maven.router.repository;
+
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ * http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+
+import org.apache.maven.wagon.Wagon;
+
+/**
+ * A component to configure wagon instances with provider-specific parameters.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface WagonConfigurator
+{
+
+ /**
+ * Configures the specified wagon instance with the given configuration.
+ *
+ * @param wagon The wagon instance to configure, must not be {@code null}.
+ * @param configuration The configuration to apply to the wagon instance, must not be {@code null}.
+ * @throws Exception If the configuration could not be applied to the wagon.
+ */
+ void configure( Wagon wagon, Object configuration )
+ throws Exception;
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonConfigurator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonProvider.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonProvider.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonProvider.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonProvider.java Tue May 24 03:33:06 2011
@@ -0,0 +1,44 @@
+package org.apache.maven.router.repository;
+
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ * http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+
+import org.apache.maven.wagon.Wagon;
+
+/**
+ * A component to acquire and release wagon instances for uploads/downloads.
+ *
+ * @author Benjamin Bentmann
+ */
+public interface WagonProvider
+{
+
+ /**
+ * Acquires a wagon instance that matches the specified role hint. The role hint is derived from the URI scheme,
+ * e.g. "http" or "file".
+ *
+ * @param roleHint The role hint to get a wagon for, must not be {@code null}.
+ * @return The requested wagon instance, never {@code null}.
+ * @throws Exception If no wagon could be retrieved for the specified role hint.
+ */
+ Wagon lookup( String roleHint )
+ throws Exception;
+
+ /**
+ * Releases the specified wagon. A wagon provider may either free any resources allocated for the wagon instance or
+ * return the instance back to a pool for future use.
+ *
+ * @param wagon The wagon to release, may be {@code null}.
+ */
+ void release( Wagon wagon );
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonRepositoryConnector.java
URL: http://svn.apache.org/viewvc/maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonRepositoryConnector.java?rev=1126854&view=auto
==============================================================================
--- maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonRepositoryConnector.java (added)
+++ maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonRepositoryConnector.java Tue May 24 03:33:06 2011
@@ -0,0 +1,955 @@
+package org.apache.maven.router.repository;
+
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ * http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.maven.wagon.ResourceDoesNotExistException;
+import org.apache.maven.wagon.Wagon;
+import org.apache.maven.wagon.WagonException;
+import org.apache.maven.wagon.authentication.AuthenticationInfo;
+import org.apache.maven.wagon.observers.ChecksumObserver;
+import org.apache.maven.wagon.proxy.ProxyInfo;
+import org.apache.maven.wagon.proxy.ProxyInfoProvider;
+import org.apache.maven.wagon.repository.Repository;
+import org.apache.maven.wagon.repository.RepositoryPermissions;
+import org.sonatype.aether.ConfigurationProperties;
+import org.sonatype.aether.RepositorySystemSession;
+import org.sonatype.aether.repository.Authentication;
+import org.sonatype.aether.repository.Proxy;
+import org.sonatype.aether.repository.RemoteRepository;
+import org.sonatype.aether.repository.RepositoryPolicy;
+import org.sonatype.aether.spi.connector.ArtifactDownload;
+import org.sonatype.aether.spi.connector.ArtifactTransfer;
+import org.sonatype.aether.spi.connector.ArtifactUpload;
+import org.sonatype.aether.spi.connector.MetadataDownload;
+import org.sonatype.aether.spi.connector.MetadataTransfer;
+import org.sonatype.aether.spi.connector.MetadataUpload;
+import org.sonatype.aether.spi.connector.RepositoryConnector;
+import org.sonatype.aether.spi.connector.Transfer;
+import org.sonatype.aether.spi.io.FileProcessor;
+import org.sonatype.aether.spi.log.Logger;
+import org.sonatype.aether.transfer.ArtifactNotFoundException;
+import org.sonatype.aether.transfer.ArtifactTransferException;
+import org.sonatype.aether.transfer.ChecksumFailureException;
+import org.sonatype.aether.transfer.MetadataNotFoundException;
+import org.sonatype.aether.transfer.MetadataTransferException;
+import org.sonatype.aether.transfer.NoRepositoryConnectorException;
+import org.sonatype.aether.transfer.TransferEvent;
+import org.sonatype.aether.transfer.TransferListener;
+import org.sonatype.aether.util.ChecksumUtils;
+import org.sonatype.aether.util.StringUtils;
+import org.sonatype.aether.util.concurrency.RunnableErrorForwarder;
+import org.sonatype.aether.util.layout.MavenDefaultLayout;
+import org.sonatype.aether.util.layout.RepositoryLayout;
+import org.sonatype.aether.util.listener.DefaultTransferEvent;
+
+/**
+ * A repository connector that uses Maven Wagon for the transfer.
+ *
+ * @author Benjamin Bentmann
+ */
+class WagonRepositoryConnector
+ implements RepositoryConnector
+{
+
+ private static final String PROP_THREADS = "aether.connector.wagon.threads";
+
+ private static final String PROP_CONFIG = "aether.connector.wagon.config";
+
+ private static final String PROP_FILE_MODE = "aether.connector.perms.fileMode";
+
+ private static final String PROP_DIR_MODE = "aether.connector.perms.dirMode";
+
+ private static final String PROP_GROUP = "aether.connector.perms.group";
+
+ private final Logger logger;
+
+ private final FileProcessor fileProcessor;
+
+ private final RemoteRepository repository;
+
+ private final RepositorySystemSession session;
+
+ private final WagonProvider wagonProvider;
+
+ private final WagonConfigurator wagonConfigurator;
+
+ private final String wagonHint;
+
+ private final Repository wagonRepo;
+
+ private final AuthenticationInfo wagonAuth;
+
+ private final ProxyInfoProvider wagonProxy;
+
+ private final RepositoryLayout layout = new MavenDefaultLayout();
+
+ private final TransferListener listener;
+
+ private final Queue<Wagon> wagons = new ConcurrentLinkedQueue<Wagon>();
+
+ private final Executor executor;
+
+ private boolean closed;
+
+ private final Map<String, String> checksumAlgos;
+
+ public WagonRepositoryConnector( WagonProvider wagonProvider, WagonConfigurator wagonConfigurator,
+ RemoteRepository repository, RepositorySystemSession session,
+ FileProcessor fileProcessor, Logger logger )
+ throws NoRepositoryConnectorException
+ {
+ this.logger = logger;
+ this.fileProcessor = fileProcessor;
+ this.wagonProvider = wagonProvider;
+ this.wagonConfigurator = wagonConfigurator;
+ this.repository = repository;
+ this.session = session;
+ this.listener = session.getTransferListener();
+
+ if ( !"default".equals( repository.getContentType() ) )
+ {
+ throw new NoRepositoryConnectorException( repository );
+ }
+
+ wagonRepo = new Repository( repository.getId(), repository.getUrl() );
+ wagonRepo.setPermissions( getPermissions( repository.getId(), session ) );
+
+ wagonHint = wagonRepo.getProtocol().toLowerCase( Locale.ENGLISH );
+ try
+ {
+ wagons.add( lookupWagon() );
+ }
+ catch ( Exception e )
+ {
+ logger.debug( e.getMessage(), e );
+ throw new NoRepositoryConnectorException( repository );
+ }
+
+ wagonAuth = getAuthenticationInfo( repository );
+ wagonProxy = getProxy( repository );
+
+ int threads = ConfigurationProperties.get( session, PROP_THREADS, Integer.MIN_VALUE );
+ if ( threads == Integer.MIN_VALUE )
+ {
+ threads = ConfigurationProperties.get( session, "maven.artifact.threads", 5 );
+ }
+ executor = getExecutor( threads );
+
+ checksumAlgos = new LinkedHashMap<String, String>();
+ checksumAlgos.put( "SHA-1", ".sha1" );
+ checksumAlgos.put( "MD5", ".md5" );
+ }
+
+ private Executor getExecutor( int threads )
+ {
+ if ( threads <= 1 )
+ {
+ return new Executor()
+ {
+ public void execute( Runnable command )
+ {
+ command.run();
+ }
+ };
+ }
+ else
+ {
+ return new ThreadPoolExecutor( threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
+ }
+ }
+
+ private static RepositoryPermissions getPermissions( String repoId, RepositorySystemSession session )
+ {
+ RepositoryPermissions result = null;
+
+ RepositoryPermissions perms = new RepositoryPermissions();
+
+ String suffix = '.' + repoId;
+
+ String fileMode = ConfigurationProperties.get( session, PROP_FILE_MODE + suffix, null );
+ if ( fileMode != null )
+ {
+ perms.setFileMode( fileMode );
+ result = perms;
+ }
+
+ String dirMode = ConfigurationProperties.get( session, PROP_DIR_MODE + suffix, null );
+ if ( dirMode != null )
+ {
+ perms.setDirectoryMode( dirMode );
+ result = perms;
+ }
+
+ String group = ConfigurationProperties.get( session, PROP_GROUP + suffix, null );
+ if ( group != null )
+ {
+ perms.setGroup( group );
+ result = perms;
+ }
+
+ return result;
+ }
+
+ private AuthenticationInfo getAuthenticationInfo( RemoteRepository repository )
+ {
+ AuthenticationInfo auth = null;
+
+ Authentication a = repository.getAuthentication();
+ if ( a != null )
+ {
+ auth = new AuthenticationInfo();
+ auth.setUserName( a.getUsername() );
+ auth.setPassword( a.getPassword() );
+ auth.setPrivateKey( a.getPrivateKeyFile() );
+ auth.setPassphrase( a.getPassphrase() );
+ }
+
+ return auth;
+ }
+
+ private ProxyInfoProvider getProxy( RemoteRepository repository )
+ {
+ ProxyInfoProvider proxy = null;
+
+ Proxy p = repository.getProxy();
+ if ( p != null )
+ {
+ final ProxyInfo prox = new ProxyInfo();
+ prox.setType( p.getType() );
+ prox.setHost( p.getHost() );
+ prox.setPort( p.getPort() );
+ if ( p.getAuthentication() != null )
+ {
+ prox.setUserName( p.getAuthentication().getUsername() );
+ prox.setPassword( p.getAuthentication().getPassword() );
+ }
+ proxy = new ProxyInfoProvider()
+ {
+ public ProxyInfo getProxyInfo( String protocol )
+ {
+ return prox;
+ }
+ };
+ }
+
+ return proxy;
+ }
+
+ private Wagon lookupWagon()
+ throws Exception
+ {
+ return wagonProvider.lookup( wagonHint );
+ }
+
+ private void releaseWagon( Wagon wagon )
+ {
+ wagonProvider.release( wagon );
+ }
+
+ private void connectWagon( Wagon wagon )
+ throws Exception
+ {
+ String userAgent =
+ ConfigurationProperties.get( session, ConfigurationProperties.USER_AGENT,
+ ConfigurationProperties.DEFAULT_USER_AGENT );
+ if ( !StringUtils.isEmpty( userAgent ) )
+ {
+ try
+ {
+ Method setHttpHeaders = wagon.getClass().getMethod( "setHttpHeaders", Properties.class );
+ Properties headers = new Properties();
+ headers.setProperty( "User-Agent", userAgent );
+ setHttpHeaders.invoke( wagon, headers );
+ }
+ catch ( NoSuchMethodException e )
+ {
+ // normal for non-http wagons
+ }
+ catch ( Exception e )
+ {
+ logger.debug( "Could not set user agent for wagon " + wagon.getClass().getName() + ": " + e );
+ }
+ }
+
+ int connectTimeout =
+ ConfigurationProperties.get( session, ConfigurationProperties.CONNECT_TIMEOUT,
+ ConfigurationProperties.DEFAULT_CONNECT_TIMEOUT );
+ int requestTimeout =
+ ConfigurationProperties.get( session, ConfigurationProperties.REQUEST_TIMEOUT,
+ ConfigurationProperties.DEFAULT_REQUEST_TIMEOUT );
+
+ wagon.setTimeout( Math.max( Math.max( connectTimeout, requestTimeout ), 0 ) );
+
+ wagon.setInteractive( ConfigurationProperties.get( session, ConfigurationProperties.INTERACTIVE,
+ ConfigurationProperties.DEFAULT_INTERACTIVE ) );
+
+ Object configuration = session.getConfigProperties().get( PROP_CONFIG + "." + repository.getId() );
+ if ( configuration != null && wagonConfigurator != null )
+ {
+ try
+ {
+ wagonConfigurator.configure( wagon, configuration );
+ }
+ catch ( Exception e )
+ {
+ String msg =
+ "Could not apply configuration for " + repository.getId() + " to wagon "
+ + wagon.getClass().getName() + ":" + e.getMessage();
+ if ( logger.isDebugEnabled() )
+ {
+ logger.warn( msg, e );
+ }
+ else
+ {
+ logger.warn( msg );
+ }
+ }
+ }
+
+ wagon.connect( wagonRepo, wagonAuth, wagonProxy );
+ }
+
+ private void disconnectWagon( Wagon wagon )
+ {
+ try
+ {
+ if ( wagon != null )
+ {
+ wagon.disconnect();
+ }
+ }
+ catch ( Exception e )
+ {
+ // too bad
+ }
+ }
+
+ Wagon pollWagon()
+ throws Exception
+ {
+ Wagon wagon = wagons.poll();
+
+ if ( wagon == null )
+ {
+ try
+ {
+ wagon = lookupWagon();
+ connectWagon( wagon );
+ }
+ catch ( Exception e )
+ {
+ releaseWagon( wagon );
+ throw e;
+ }
+ }
+ else if ( wagon.getRepository() == null )
+ {
+ try
+ {
+ connectWagon( wagon );
+ }
+ catch ( Exception e )
+ {
+ wagons.add( wagon );
+ throw e;
+ }
+ }
+
+ return wagon;
+ }
+
+ private <T> Collection<T> safe( Collection<T> items )
+ {
+ return ( items != null ) ? items : Collections.<T> emptyList();
+ }
+
+ private File getTmpFile( String path )
+ {
+ File file;
+ do
+ {
+ file = new File( path + ".tmp" + UUID.randomUUID().toString().replace( "-", "" ).substring( 0, 16 ) );
+ }
+ while ( file.exists() );
+ return file;
+ }
+
+ public void get( Collection<? extends ArtifactDownload> artifactDownloads,
+ Collection<? extends MetadataDownload> metadataDownloads )
+ {
+ if ( closed )
+ {
+ throw new IllegalStateException( "connector closed" );
+ }
+
+ artifactDownloads = safe( artifactDownloads );
+ metadataDownloads = safe( metadataDownloads );
+
+ Collection<GetTask<?>> tasks = new ArrayList<GetTask<?>>();
+
+ RunnableErrorForwarder errorForwarder = new RunnableErrorForwarder();
+
+ for ( MetadataDownload download : metadataDownloads )
+ {
+ String resource = layout.getPath( download.getMetadata() ).getPath();
+ GetTask<?> task =
+ new GetTask<MetadataTransfer>( resource, download.getFile(), download.getChecksumPolicy(), download,
+ METADATA );
+ tasks.add( task );
+ executor.execute( errorForwarder.wrap( task ) );
+ }
+
+ for ( ArtifactDownload download : artifactDownloads )
+ {
+ String resource = layout.getPath( download.getArtifact() ).getPath();
+ GetTask<?> task =
+ new GetTask<ArtifactTransfer>( resource, download.isExistenceCheck() ? null : download.getFile(),
+ download.getChecksumPolicy(), download, ARTIFACT );
+ tasks.add( task );
+ executor.execute( errorForwarder.wrap( task ) );
+ }
+
+ errorForwarder.await();
+
+ for ( GetTask<?> task : tasks )
+ {
+ task.flush();
+ }
+ }
+
+ public void put( Collection<? extends ArtifactUpload> artifactUploads,
+ Collection<? extends MetadataUpload> metadataUploads )
+ {
+ if ( closed )
+ {
+ throw new IllegalStateException( "connector closed" );
+ }
+
+ artifactUploads = safe( artifactUploads );
+ metadataUploads = safe( metadataUploads );
+
+ for ( ArtifactUpload upload : artifactUploads )
+ {
+ String path = layout.getPath( upload.getArtifact() ).getPath();
+
+ PutTask<?> task = new PutTask<ArtifactTransfer>( path, upload.getFile(), upload, ARTIFACT );
+ task.run();
+ task.flush();
+ }
+
+ for ( MetadataUpload upload : metadataUploads )
+ {
+ String path = layout.getPath( upload.getMetadata() ).getPath();
+
+ PutTask<?> task = new PutTask<MetadataTransfer>( path, upload.getFile(), upload, METADATA );
+ task.run();
+ task.flush();
+ }
+ }
+
+ public void close()
+ {
+ closed = true;
+
+ for ( Wagon wagon = wagons.poll(); wagon != null; wagon = wagons.poll() )
+ {
+ disconnectWagon( wagon );
+ releaseWagon( wagon );
+ }
+
+ shutdown( executor );
+ }
+
+ private void shutdown( Executor executor )
+ {
+ if ( executor instanceof ExecutorService )
+ {
+ ( (ExecutorService) executor ).shutdown();
+ }
+ }
+
+ @Override
+ protected void finalize()
+ throws Throwable
+ {
+ try
+ {
+ close();
+ }
+ finally
+ {
+ super.finalize();
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.valueOf( repository );
+ }
+
+ class GetTask<T extends Transfer>
+ implements Runnable
+ {
+
+ private final T download;
+
+ private final String path;
+
+ private final File file;
+
+ private final String checksumPolicy;
+
+ private volatile Exception exception;
+
+ private final ExceptionWrapper<T> wrapper;
+
+ public GetTask( String path, File file, String checksumPolicy, T download, ExceptionWrapper<T> wrapper )
+ {
+ this.path = path;
+ this.file = file;
+ this.checksumPolicy = checksumPolicy;
+ this.download = download;
+ this.wrapper = wrapper;
+ }
+
+ public T getDownload()
+ {
+ return download;
+ }
+
+ public Exception getException()
+ {
+ return exception;
+ }
+
+ public void run()
+ {
+ download.setState( Transfer.State.ACTIVE );
+
+ WagonTransferListenerAdapter wagonListener = null;
+ if ( listener != null )
+ {
+ wagonListener =
+ new WagonTransferListenerAdapter( listener, wagonRepo.getUrl(), path, file, download.getTrace() );
+ }
+
+ try
+ {
+ if ( listener != null )
+ {
+ DefaultTransferEvent event = wagonListener.newEvent();
+ event.setRequestType( TransferEvent.RequestType.GET );
+ event.setType( TransferEvent.EventType.INITIATED );
+ listener.transferInitiated( event );
+ }
+
+ File tmp = ( file != null ) ? getTmpFile( file.getPath() ) : null;
+
+ Wagon wagon = pollWagon();
+
+ try
+ {
+ if ( file == null )
+ {
+ if ( !wagon.resourceExists( path ) )
+ {
+ throw new ResourceDoesNotExistException( "Could not find " + path + " in "
+ + wagonRepo.getUrl() );
+ }
+ }
+ else
+ {
+ for ( int trial = 1; trial >= 0; trial-- )
+ {
+ ChecksumObserver sha1 = new ChecksumObserver( "SHA-1" );
+ ChecksumObserver md5 = new ChecksumObserver( "MD5" );
+ try
+ {
+ wagon.addTransferListener( wagonListener );
+ wagon.addTransferListener( md5 );
+ wagon.addTransferListener( sha1 );
+
+ /*
+ * NOTE: AbstractWagon.createParentDirectories() uses File.mkdirs() which is not
+ * thread-safe in all JREs.
+ */
+ fileProcessor.mkdirs( tmp.getParentFile() );
+
+ wagon.get( path, tmp );
+ }
+ finally
+ {
+ wagon.removeTransferListener( wagonListener );
+ wagon.removeTransferListener( md5 );
+ wagon.removeTransferListener( sha1 );
+ }
+
+ if ( RepositoryPolicy.CHECKSUM_POLICY_IGNORE.equals( checksumPolicy ) )
+ {
+ break;
+ }
+ else
+ {
+ try
+ {
+ if ( !verifyChecksum( wagon, sha1.getActualChecksum(), ".sha1" )
+ && !verifyChecksum( wagon, md5.getActualChecksum(), ".md5" ) )
+ {
+ trial = 0;
+ throw new ChecksumFailureException( "Checksum validation failed"
+ + ", no checksums available from the repository" );
+ }
+ break;
+ }
+ catch ( ChecksumFailureException e )
+ {
+ if ( trial <= 0 && RepositoryPolicy.CHECKSUM_POLICY_FAIL.equals( checksumPolicy ) )
+ {
+ throw e;
+ }
+ if ( listener != null )
+ {
+ DefaultTransferEvent event = wagonListener.newEvent();
+ event.setRequestType( TransferEvent.RequestType.GET );
+ event.setType( TransferEvent.EventType.CORRUPTED );
+ event.setException( e );
+ listener.transferCorrupted( event );
+ }
+ }
+ }
+ }
+
+ rename( tmp, file );
+ }
+
+ if ( listener != null )
+ {
+ DefaultTransferEvent event = wagonListener.newEvent();
+ event.setRequestType( TransferEvent.RequestType.GET );
+ event.setType( TransferEvent.EventType.SUCCEEDED );
+ listener.transferSucceeded( event );
+ }
+ }
+ finally
+ {
+ if ( tmp != null )
+ {
+ tmp.delete();
+ }
+ wagons.add( wagon );
+ }
+ }
+ catch ( Exception e )
+ {
+ exception = e;
+
+ if ( listener != null )
+ {
+ DefaultTransferEvent event = wagonListener.newEvent();
+ event.setRequestType( TransferEvent.RequestType.GET );
+ event.setType( TransferEvent.EventType.FAILED );
+ event.setException( e );
+ listener.transferFailed( event );
+ }
+ }
+ }
+
+ public void flush()
+ {
+ flush( null );
+ }
+
+ public void flush( Exception exception )
+ {
+ Exception e = this.exception;
+ wrapper.wrap( download, ( e != null ) ? e : exception, repository );
+ download.setState( Transfer.State.DONE );
+ }
+
+ private boolean verifyChecksum( Wagon wagon, String actual, String ext )
+ throws ChecksumFailureException
+ {
+ File tmp = getTmpFile( file.getPath() + ext );
+
+ try
+ {
+ try
+ {
+ wagon.get( path + ext, tmp );
+ }
+ catch ( ResourceDoesNotExistException e )
+ {
+ return false;
+ }
+ catch ( WagonException e )
+ {
+ throw new ChecksumFailureException( e );
+ }
+
+ String expected;
+
+ try
+ {
+ expected = ChecksumUtils.read( tmp );
+ }
+ catch ( IOException e )
+ {
+ throw new ChecksumFailureException( e );
+ }
+
+ if ( expected.equalsIgnoreCase( actual ) )
+ {
+ try
+ {
+ rename( tmp, new File( file.getPath() + ext ) );
+ }
+ catch ( IOException e )
+ {
+ // ignored, non-critical
+ }
+ }
+ else
+ {
+ throw new ChecksumFailureException( expected, actual );
+ }
+ }
+ finally
+ {
+ tmp.delete();
+ }
+
+ return true;
+ }
+
+ private void rename( File from, File to )
+ throws IOException
+ {
+ if ( !from.exists() )
+ {
+ /*
+ * NOTE: Wagon (1.0-beta-6) doesn't create the destination file when transferring a 0-byte resource. So
+ * if the resource we asked for didn't cause any exception but doesn't show up in the tmp file either,
+ * Wagon tells us in its weird way the file is empty.
+ */
+ fileProcessor.write( to, "" );
+ }
+ else
+ {
+ fileProcessor.move( from, to );
+ }
+ }
+
+ }
+
+ class PutTask<T extends Transfer>
+ implements Runnable
+ {
+
+ private final T upload;
+
+ private final ExceptionWrapper<T> wrapper;
+
+ private final String path;
+
+ private final File file;
+
+ private volatile Exception exception;
+
+ public PutTask( String path, File file, T upload, ExceptionWrapper<T> wrapper )
+ {
+ this.path = path;
+ this.file = file;
+ this.upload = upload;
+ this.wrapper = wrapper;
+ }
+
+ public void run()
+ {
+ upload.setState( Transfer.State.ACTIVE );
+
+ WagonTransferListenerAdapter wagonListener = null;
+ if ( listener != null )
+ {
+ wagonListener =
+ new WagonTransferListenerAdapter( listener, wagonRepo.getUrl(), path, file, upload.getTrace() );
+ }
+
+ try
+ {
+ if ( listener != null )
+ {
+ DefaultTransferEvent event = wagonListener.newEvent();
+ event.setRequestType( TransferEvent.RequestType.PUT );
+ event.setType( TransferEvent.EventType.INITIATED );
+ listener.transferInitiated( event );
+ }
+
+ Wagon wagon = pollWagon();
+
+ try
+ {
+ try
+ {
+ wagon.addTransferListener( wagonListener );
+
+ wagon.put( file, path );
+ }
+ finally
+ {
+ wagon.removeTransferListener( wagonListener );
+ }
+
+ uploadChecksums( wagon, file, path );
+
+ if ( listener != null )
+ {
+ DefaultTransferEvent event = wagonListener.newEvent();
+ event.setRequestType( TransferEvent.RequestType.PUT );
+ event.setType( TransferEvent.EventType.SUCCEEDED );
+ listener.transferSucceeded( event );
+ }
+ }
+ finally
+ {
+ wagons.add( wagon );
+ }
+ }
+ catch ( Exception e )
+ {
+ exception = e;
+
+ if ( listener != null )
+ {
+ DefaultTransferEvent event = wagonListener.newEvent();
+ event.setRequestType( TransferEvent.RequestType.PUT );
+ event.setType( TransferEvent.EventType.FAILED );
+ event.setException( e );
+ listener.transferFailed( event );
+ }
+ }
+ }
+
+ public void flush()
+ {
+ wrapper.wrap( upload, exception, repository );
+ upload.setState( Transfer.State.DONE );
+ }
+
+ private void uploadChecksums( Wagon wagon, File file, String path )
+ {
+ try
+ {
+ Map<String, Object> checksums = ChecksumUtils.calc( file, checksumAlgos.keySet() );
+ for ( Map.Entry<String, Object> entry : checksums.entrySet() )
+ {
+ uploadChecksum( wagon, file, path, entry.getKey(), entry.getValue() );
+ }
+ }
+ catch ( IOException e )
+ {
+ logger.debug( "Failed to upload checksums for " + file + ": " + e.getMessage(), e );
+ }
+ }
+
+ private void uploadChecksum( Wagon wagon, File file, String path, String algo, Object checksum )
+ {
+ try
+ {
+ if ( checksum instanceof Exception )
+ {
+ throw (Exception) checksum;
+ }
+
+ String ext = checksumAlgos.get( algo );
+
+ File tmpFile = File.createTempFile( "checksum", ext );
+ try
+ {
+ fileProcessor.write( tmpFile, String.valueOf( checksum ) );
+ wagon.put( tmpFile, path + ext );
+ }
+ finally
+ {
+ tmpFile.delete();
+ }
+ }
+ catch ( Exception e )
+ {
+ logger.debug( "Failed to upload " + algo + " checksum for " + file + ": " + e.getMessage(), e );
+ }
+ }
+
+ }
+
+ static interface ExceptionWrapper<T>
+ {
+
+ void wrap( T transfer, Exception e, RemoteRepository repository );
+
+ }
+
+ private static final ExceptionWrapper<MetadataTransfer> METADATA = new ExceptionWrapper<MetadataTransfer>()
+ {
+ public void wrap( MetadataTransfer transfer, Exception e, RemoteRepository repository )
+ {
+ MetadataTransferException ex = null;
+ if ( e instanceof ResourceDoesNotExistException )
+ {
+ ex = new MetadataNotFoundException( transfer.getMetadata(), repository );
+ }
+ else if ( e != null )
+ {
+ ex = new MetadataTransferException( transfer.getMetadata(), repository, e );
+ }
+ transfer.setException( ex );
+ }
+ };
+
+ private static final ExceptionWrapper<ArtifactTransfer> ARTIFACT = new ExceptionWrapper<ArtifactTransfer>()
+ {
+ public void wrap( ArtifactTransfer transfer, Exception e, RemoteRepository repository )
+ {
+ ArtifactTransferException ex = null;
+ if ( e instanceof ResourceDoesNotExistException )
+ {
+ ex = new ArtifactNotFoundException( transfer.getArtifact(), repository );
+ }
+ else if ( e != null )
+ {
+ ex = new ArtifactTransferException( transfer.getArtifact(), repository, e );
+ }
+ transfer.setException( ex );
+ }
+ };
+
+}
Propchange: maven/maven-3/branches/mirror-group-routing/maven-routem-aether-wagon-connector/src/main/java/org/apache/maven/router/repository/WagonRepositoryConnector.java
------------------------------------------------------------------------------
svn:eol-style = native