View Javadoc
1   package org.eclipse.aether.spi.connector.layout;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.net.URI;
23  import java.util.List;
24  
25  import static java.util.Objects.requireNonNull;
26  
27  import org.eclipse.aether.artifact.Artifact;
28  import org.eclipse.aether.metadata.Metadata;
29  import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
30  
31  /**
32   * The layout for a remote repository whose artifacts/metadata can be addressed via URIs.
33   * <p>
34   * <strong>Note:</strong> Implementations must be stateless.
35   */
36  public interface RepositoryLayout
37  {
38  
39      /**
40       * A descriptor for a checksum location. This descriptor simply associates the location of a checksum file with the
41       * underlying checksum algorithm used to calculate/verify it.
42       */
43      final class ChecksumLocation
44      {
45          private final URI location;
46  
47          private final ChecksumAlgorithmFactory checksumAlgorithmFactory;
48  
49          /**
50           * Creates a new checksum file descriptor with the specified algorithm and location. The method
51           * {@link #forLocation(URI, ChecksumAlgorithmFactory)} is usually more convenient though.
52           *
53           * @param location                 The relative URI to the checksum file within a repository, must not be {@code
54           *                                 null}.
55           * @param checksumAlgorithmFactory The checksum type used to calculate the checksum, must not be {@code null}.
56           */
57          public ChecksumLocation( URI location, ChecksumAlgorithmFactory checksumAlgorithmFactory )
58          {
59              verify( location, checksumAlgorithmFactory );
60              this.location = location;
61              this.checksumAlgorithmFactory = checksumAlgorithmFactory;
62          }
63  
64          /**
65           * Creates a checksum descriptor for the specified artifact/metadata location and algorithm. The location
66           * of the checksum file itself is derived from the supplied resource URI by appending the file extension
67           * specified by the algorithm factory. See {@link ChecksumAlgorithmFactory#getFileExtension()}.
68           *
69           * @param location                 The relative URI to the artifact/metadata whose checksum file is being
70           *                                 obtained, must not be
71           *                                 {@code null} and must not have a query or fragment part.
72           * @param checksumAlgorithmFactory The algorithm used to calculate the checksum, must not be {@code null}.
73           * @return The checksum file descriptor, never {@code null}.
74           */
75          public static ChecksumLocation forLocation( URI location, ChecksumAlgorithmFactory checksumAlgorithmFactory )
76          {
77              verify( location, checksumAlgorithmFactory );
78              if ( location.getRawQuery() != null )
79              {
80                  throw new IllegalArgumentException( "resource location must not have query parameters: " + location );
81              }
82              if ( location.getRawFragment() != null )
83              {
84                  throw new IllegalArgumentException( "resource location must not have a fragment: " + location );
85              }
86              return new ChecksumLocation( URI.create( location + "." + checksumAlgorithmFactory.getFileExtension() ),
87                      checksumAlgorithmFactory );
88          }
89  
90          private static void verify( URI location, ChecksumAlgorithmFactory checksumAlgorithmFactory )
91          {
92              requireNonNull( location, "checksum location cannot be null" );
93              if ( location.isAbsolute() )
94              {
95                  throw new IllegalArgumentException( "checksum location must be relative" );
96              }
97              requireNonNull( checksumAlgorithmFactory, "checksum algorithm factory cannot be null" );
98          }
99  
100         /**
101          * Gets the {@link ChecksumAlgorithmFactory} that is used to calculate the checksum.
102          *
103          * @return The checksum factory, never {@code null}.
104          */
105         public ChecksumAlgorithmFactory getChecksumAlgorithmFactory()
106         {
107             return checksumAlgorithmFactory;
108         }
109 
110         /**
111          * Gets the location of the checksum file with a remote repository. The URI is relative to the root directory of
112          * the repository.
113          *
114          * @return The relative URI to the checksum file, never {@code null}.
115          */
116         public URI getLocation()
117         {
118             return location;
119         }
120 
121         @Override
122         public String toString()
123         {
124             return location + " (" + checksumAlgorithmFactory.getName() + ")";
125         }
126     }
127 
128     /**
129      * Returns immutable list of {@link ChecksumAlgorithmFactory} this instance of layout uses, never {@code null}.
130      * The order also represents the order how remote external checksums are retrieved and validated.
131      *
132      * @see org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind
133      * @since 1.8.0
134      */
135     List<ChecksumAlgorithmFactory> getChecksumAlgorithmFactories();
136 
137     /**
138      * Tells whether given artifact have remote external checksums according to current layout or not. If it returns
139      * {@code true}, then layout configured checksums will be expected: on upload they will be calculated and deployed
140      * along artifact, on download they will be retrieved and validated.
141      *
142      * If it returns {@code false} the given artifacts will have checksums omitted: on upload they will not be
143      * calculated and deployed, and on download they will be not retrieved nor validated.
144      *
145      * The result affects only layout provided checksums. See
146      * {@link org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind#REMOTE_EXTERNAL}.
147      * On download, the {@link org.eclipse.aether.spi.connector.layout.RepositoryLayout#getChecksumAlgorithmFactories()}
148      * layout required checksums are calculated, and non layout-provided checksums are still utilized.
149      *
150      * Typical case to return {@code false} (to omit checksums) is for artifact signatures, that are already a
151      * "sub-artifact" of some main artifact (for example a JAR), and they can be validated by some other means.
152      *
153      * @see org.eclipse.aether.spi.connector.checksum.ChecksumPolicy.ChecksumKind
154      * @see #getChecksumAlgorithmFactories()
155      * @since 1.8.0
156      */
157     boolean hasChecksums( Artifact artifact );
158 
159     /**
160      * Gets the location within a remote repository where the specified artifact resides. The URI is relative to the
161      * root directory of the repository.
162      *
163      * @param artifact The artifact to get the URI for, must not be {@code null}.
164      * @param upload   {@code false} if the artifact is being downloaded, {@code true} if the artifact is being
165      *                 uploaded.
166      * @return The relative URI to the artifact, never {@code null}.
167      */
168     URI getLocation( Artifact artifact, boolean upload );
169 
170     /**
171      * Gets the location within a remote repository where the specified metadata resides. The URI is relative to the
172      * root directory of the repository.
173      *
174      * @param metadata The metadata to get the URI for, must not be {@code null}.
175      * @param upload   {@code false} if the metadata is being downloaded, {@code true} if the metadata is being
176      *                 uploaded.
177      * @return The relative URI to the metadata, never {@code null}.
178      */
179     URI getLocation( Metadata metadata, boolean upload );
180 
181     /**
182      * Gets the checksums files that a remote repository keeps to help detect data corruption during transfers of the
183      * specified artifact.
184      *
185      * @param artifact The artifact to get the checksum files for, must not be {@code null}.
186      * @param upload   {@code false} if the checksums are being downloaded/verified, {@code true} if the checksums are
187      *                 being uploaded/created.
188      * @param location The relative URI to the artifact within the repository as previously obtained from
189      *                 {@link #getLocation(Artifact, boolean)}, must not be {@code null}.
190      * @return The checksum files for the given artifact, possibly empty but never {@code null}. If empty, that means
191      * that this layout does not provide checksums for given artifact.
192      */
193     List<ChecksumLocation> getChecksumLocations( Artifact artifact, boolean upload, URI location );
194 
195     /**
196      * Gets the checksums files that a remote repository keeps to help detect data corruption during transfers of the
197      * specified metadata.
198      *
199      * @param metadata The metadata to get the checksum files for, must not be {@code null}.
200      * @param upload   {@code false} if the checksums are being downloaded/verified, {@code true} if the checksums are
201      *                 being uploaded/created.
202      * @param location The relative URI to the metadata within the repository as previously obtained from
203      *                 {@link #getLocation(Metadata, boolean)}, must not be {@code null}.
204      * @return The checksum files for the given metadata, possibly empty but never {@code null}. If empty, that means
205      * that this layout does not provide checksums for given artifact.
206      */
207     List<ChecksumLocation> getChecksumLocations( Metadata metadata, boolean upload, URI location );
208 
209 }