001package org.apache.maven.artifact.deployer;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.util.Map;
024import java.util.concurrent.ConcurrentHashMap;
025
026import org.apache.maven.RepositoryUtils;
027import org.apache.maven.artifact.Artifact;
028import org.apache.maven.artifact.metadata.ArtifactMetadata;
029import org.apache.maven.artifact.repository.ArtifactRepository;
030import org.apache.maven.artifact.repository.DefaultArtifactRepository;
031import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
032import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata;
033import org.apache.maven.artifact.repository.metadata.MetadataBridge;
034import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
035import org.apache.maven.plugin.LegacySupport;
036import org.apache.maven.project.artifact.ProjectArtifactMetadata;
037import org.codehaus.plexus.component.annotations.Component;
038import org.codehaus.plexus.component.annotations.Requirement;
039import org.codehaus.plexus.logging.AbstractLogEnabled;
040import org.eclipse.aether.RepositorySystem;
041import org.eclipse.aether.RepositorySystemSession;
042import org.eclipse.aether.RequestTrace;
043import org.eclipse.aether.deployment.DeployRequest;
044import org.eclipse.aether.deployment.DeployResult;
045import org.eclipse.aether.deployment.DeploymentException;
046import org.eclipse.aether.metadata.MergeableMetadata;
047import org.eclipse.aether.repository.RemoteRepository;
048import org.eclipse.aether.util.artifact.SubArtifact;
049
050@Component( role = ArtifactDeployer.class, instantiationStrategy = "per-lookup" )
051public class DefaultArtifactDeployer
052    extends AbstractLogEnabled
053    implements ArtifactDeployer
054{
055
056    @Requirement
057    private RepositorySystem repoSystem;
058
059    @Requirement
060    private LegacySupport legacySupport;
061
062    private Map<Object, MergeableMetadata> relatedMetadata = new ConcurrentHashMap<>();
063
064    /**
065     * @deprecated we want to use the artifact method only, and ensure artifact.file is set
066     *             correctly.
067     */
068    @Deprecated
069    public void deploy( String basedir, String finalName, Artifact artifact, ArtifactRepository deploymentRepository,
070                        ArtifactRepository localRepository )
071        throws ArtifactDeploymentException
072    {
073        String extension = artifact.getArtifactHandler().getExtension();
074        File source = new File( basedir, finalName + "." + extension );
075        deploy( source, artifact, deploymentRepository, localRepository );
076    }
077
078    public void deploy( File source, Artifact artifact, ArtifactRepository deploymentRepository,
079                        ArtifactRepository localRepository )
080        throws ArtifactDeploymentException
081    {
082        RepositorySystemSession session =
083            LegacyLocalRepositoryManager.overlay( localRepository, legacySupport.getRepositorySession(), repoSystem );
084
085        DeployRequest request = new DeployRequest();
086
087        request.setTrace( RequestTrace.newChild( null, legacySupport.getSession().getCurrentProject() ) );
088
089        org.eclipse.aether.artifact.Artifact mainArtifact = RepositoryUtils.toArtifact( artifact );
090        mainArtifact = mainArtifact.setFile( source );
091        request.addArtifact( mainArtifact );
092
093        String versionKey = artifact.getGroupId() + ':' + artifact.getArtifactId();
094        String snapshotKey = null;
095        if ( artifact.isSnapshot() )
096        {
097            snapshotKey = versionKey + ':' + artifact.getBaseVersion();
098            request.addMetadata( relatedMetadata.get( snapshotKey ) );
099        }
100        request.addMetadata( relatedMetadata.get( versionKey ) );
101
102        for ( ArtifactMetadata metadata : artifact.getMetadataList() )
103        {
104            if ( metadata instanceof ProjectArtifactMetadata )
105            {
106                org.eclipse.aether.artifact.Artifact pomArtifact = new SubArtifact( mainArtifact, "", "pom" );
107                pomArtifact = pomArtifact.setFile( ( (ProjectArtifactMetadata) metadata ).getFile() );
108                request.addArtifact( pomArtifact );
109            }
110            else if ( metadata instanceof SnapshotArtifactRepositoryMetadata
111                || metadata instanceof ArtifactRepositoryMetadata )
112            {
113                // eaten, handled by repo system
114            }
115            else
116            {
117                request.addMetadata( new MetadataBridge( metadata ) );
118            }
119        }
120
121        RemoteRepository remoteRepo = RepositoryUtils.toRepo( deploymentRepository );
122        /*
123         * NOTE: This provides backward-compat with maven-deploy-plugin:2.4 which bypasses the repository factory when
124         * using an alternative deployment location.
125         */
126        if ( deploymentRepository instanceof DefaultArtifactRepository
127            && deploymentRepository.getAuthentication() == null )
128        {
129            RemoteRepository.Builder builder = new RemoteRepository.Builder( remoteRepo );
130            builder.setAuthentication( session.getAuthenticationSelector().getAuthentication( remoteRepo ) );
131            builder.setProxy( session.getProxySelector().getProxy( remoteRepo ) );
132            remoteRepo = builder.build();
133        }
134        request.setRepository( remoteRepo );
135
136        DeployResult result;
137        try
138        {
139            result = repoSystem.deploy( session, request );
140        }
141        catch ( DeploymentException e )
142        {
143            throw new ArtifactDeploymentException( e.getMessage(), e );
144        }
145
146        for ( Object metadata : result.getMetadata() )
147        {
148            if ( metadata.getClass().getName().endsWith( ".internal.VersionsMetadata" ) )
149            {
150                relatedMetadata.put( versionKey, (MergeableMetadata) metadata );
151            }
152            if ( snapshotKey != null && metadata.getClass().getName().endsWith( ".internal.RemoteSnapshotMetadata" ) )
153            {
154                relatedMetadata.put( snapshotKey, (MergeableMetadata) metadata );
155            }
156        }
157
158        artifact.setResolvedVersion( result.getArtifacts().iterator().next().getVersion() );
159    }
160
161}