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