001package org.eclipse.aether.internal.impl;
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.net.URI;
023import java.net.URISyntaxException;
024import java.util.Arrays;
025import java.util.ArrayList;
026import java.util.Collections;
027import java.util.List;
028
029import javax.inject.Named;
030
031import org.eclipse.aether.RepositorySystemSession;
032import org.eclipse.aether.artifact.Artifact;
033import org.eclipse.aether.metadata.Metadata;
034import org.eclipse.aether.repository.RemoteRepository;
035import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
036import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
037import org.eclipse.aether.transfer.NoRepositoryLayoutException;
038import org.eclipse.aether.util.ConfigUtils;
039
040/**
041 * Provides a Maven-2 repository layout for repositories with content type {@code "default"}.
042 */
043@Named( "maven2" )
044public final class Maven2RepositoryLayoutFactory
045    implements RepositoryLayoutFactory
046{
047
048    static final String CONFIG_PROP_SIGNATURE_CHECKSUMS = "aether.checksums.forSignature";
049    static final String CONFIG_PROP_CHECKSUMS_ALGORITHMS = "aether.checksums.algorithms";
050
051    static final String DEFAULT_CHECKSUMS_ALGORITHMS = "SHA-1,MD5";
052
053    private float priority;
054
055    public float getPriority()
056    {
057        return priority;
058    }
059
060    /**
061     * Sets the priority of this component.
062     *
063     * @param priority The priority.
064     * @return This component for chaining, never {@code null}.
065     */
066    public Maven2RepositoryLayoutFactory setPriority( float priority )
067    {
068        this.priority = priority;
069        return this;
070    }
071
072    public RepositoryLayout newInstance( RepositorySystemSession session, RemoteRepository repository )
073        throws NoRepositoryLayoutException
074    {
075        if ( !"default".equals( repository.getContentType() ) )
076        {
077            throw new NoRepositoryLayoutException( repository );
078        }
079        boolean forSignature = ConfigUtils.getBoolean( session, false, CONFIG_PROP_SIGNATURE_CHECKSUMS );
080        List<String> checksumsAlgorithms = Arrays.asList( ConfigUtils.getString( session,
081                DEFAULT_CHECKSUMS_ALGORITHMS, CONFIG_PROP_CHECKSUMS_ALGORITHMS ).split( "," ) );
082
083        return forSignature
084                ? new Maven2RepositoryLayout( checksumsAlgorithms )
085                : new Maven2RepositoryLayoutEx( checksumsAlgorithms );
086    }
087
088    private static class Maven2RepositoryLayout
089        implements RepositoryLayout
090    {
091
092        private final List<String> checksumsAlgorithms;
093
094        protected Maven2RepositoryLayout( List<String> checksumsAlgorithms )
095        {
096            this.checksumsAlgorithms = checksumsAlgorithms;
097        }
098
099        private URI toUri( String path )
100        {
101            try
102            {
103                return new URI( null, null, path, null );
104            }
105            catch ( URISyntaxException e )
106            {
107                throw new IllegalStateException( e );
108            }
109        }
110
111        public URI getLocation( Artifact artifact, boolean upload )
112        {
113            StringBuilder path = new StringBuilder( 128 );
114
115            path.append( artifact.getGroupId().replace( '.', '/' ) ).append( '/' );
116
117            path.append( artifact.getArtifactId() ).append( '/' );
118
119            path.append( artifact.getBaseVersion() ).append( '/' );
120
121            path.append( artifact.getArtifactId() ).append( '-' ).append( artifact.getVersion() );
122
123            if ( artifact.getClassifier().length() > 0 )
124            {
125                path.append( '-' ).append( artifact.getClassifier() );
126            }
127
128            if ( artifact.getExtension().length() > 0 )
129            {
130                path.append( '.' ).append( artifact.getExtension() );
131            }
132
133            return toUri( path.toString() );
134        }
135
136        public URI getLocation( Metadata metadata, boolean upload )
137        {
138            StringBuilder path = new StringBuilder( 128 );
139
140            if ( metadata.getGroupId().length() > 0 )
141            {
142                path.append( metadata.getGroupId().replace( '.', '/' ) ).append( '/' );
143
144                if ( metadata.getArtifactId().length() > 0 )
145                {
146                    path.append( metadata.getArtifactId() ).append( '/' );
147
148                    if ( metadata.getVersion().length() > 0 )
149                    {
150                        path.append( metadata.getVersion() ).append( '/' );
151                    }
152                }
153            }
154
155            path.append( metadata.getType() );
156
157            return toUri( path.toString() );
158        }
159
160        public List<Checksum> getChecksums( Artifact artifact, boolean upload, URI location )
161        {
162            return getChecksums( location );
163        }
164
165        public List<Checksum> getChecksums( Metadata metadata, boolean upload, URI location )
166        {
167            return getChecksums( location );
168        }
169
170        private List<Checksum> getChecksums( URI location )
171        {
172            List<Checksum> checksums = new ArrayList<>( checksumsAlgorithms.size() );
173            for ( String algorithm : checksumsAlgorithms )
174            {
175                checksums.add( Checksum.forLocation( location, algorithm ) );
176            }
177            return checksums;
178        }
179
180    }
181
182    private static class Maven2RepositoryLayoutEx
183        extends Maven2RepositoryLayout
184    {
185
186        protected Maven2RepositoryLayoutEx( List<String> checksumsAlgorithms )
187        {
188            super( checksumsAlgorithms );
189        }
190
191        @Override
192        public List<Checksum> getChecksums( Artifact artifact, boolean upload, URI location )
193        {
194            if ( isSignature( artifact.getExtension() ) )
195            {
196                return Collections.emptyList();
197            }
198            return super.getChecksums( artifact, upload, location );
199        }
200
201        private boolean isSignature( String extension )
202        {
203            return extension.endsWith( ".asc" );
204        }
205
206    }
207
208}