View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.eclipse.aether.internal.impl.checksum;
20  
21  import java.io.IOException;
22  import java.io.UncheckedIOException;
23  import java.nio.file.Path;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.eclipse.aether.ConfigurationProperties;
28  import org.eclipse.aether.RepositorySystemSession;
29  import org.eclipse.aether.artifact.Artifact;
30  import org.eclipse.aether.repository.ArtifactRepository;
31  import org.eclipse.aether.spi.checksums.TrustedChecksumsSource;
32  import org.eclipse.aether.spi.connector.checksum.ChecksumAlgorithmFactory;
33  import org.eclipse.aether.util.DirectoryUtils;
34  
35  import static java.util.Objects.requireNonNull;
36  
37  /**
38   * Support class for implementing {@link TrustedChecksumsSource} backed by local filesystem. It implements basic support
39   * like basedir calculation, "enabled" flag and "originAware" flag.
40   * <p>
41   * The configuration keys supported:
42   * <ul>
43   *     <li><pre>aether.trustedChecksumsSource.${name}</pre> (boolean) must be explicitly set to "true"
44   *     to become enabled</li>
45   *     <li><pre>aether.trustedChecksumsSource.${name}.basedir</pre> (string, path) directory from where implementation
46   *     can use files. May be relative path (then is resolved against local repository basedir) or absolute. If unset,
47   *     default value is ".checksums" and is resolved against local repository basedir.</li>
48   *     <li><pre>aether.trustedChecksumsSource.${name}.originAware</pre> (boolean) whether to make implementation
49   *     "originAware", to factor in origin repository ID as well or not.</li>
50   * </ul>
51   * <p>
52   * This implementation ensures that implementations have "name" property, used in configuration properties above.
53   *
54   * @since 1.9.0
55   */
56  abstract class FileTrustedChecksumsSourceSupport implements TrustedChecksumsSource {
57      protected static final String CONFIG_PROPS_PREFIX =
58              ConfigurationProperties.PREFIX_AETHER + "trustedChecksumsSource.";
59  
60      /**
61       * This implementation will call into underlying code only if enabled, and will enforce non-{@code null} return
62       * value. In worst case, empty map should be returned, meaning "no trusted checksums available".
63       */
64      @Override
65      public Map<String, String> getTrustedArtifactChecksums(
66              RepositorySystemSession session,
67              Artifact artifact,
68              ArtifactRepository artifactRepository,
69              List<ChecksumAlgorithmFactory> checksumAlgorithmFactories) {
70          requireNonNull(session, "session is null");
71          requireNonNull(artifact, "artifact is null");
72          requireNonNull(artifactRepository, "artifactRepository is null");
73          requireNonNull(checksumAlgorithmFactories, "checksumAlgorithmFactories is null");
74          if (isEnabled(session)) {
75              return requireNonNull(
76                      doGetTrustedArtifactChecksums(session, artifact, artifactRepository, checksumAlgorithmFactories));
77          }
78          return null;
79      }
80  
81      /**
82       * This implementation will call into underlying code only if enabled. Underlying implementation may still choose
83       * to return {@code null}.
84       */
85      @Override
86      public Writer getTrustedArtifactChecksumsWriter(RepositorySystemSession session) {
87          requireNonNull(session, "session is null");
88          if (isEnabled(session)) {
89              return doGetTrustedArtifactChecksumsWriter(session);
90          }
91          return null;
92      }
93  
94      /**
95       * Implementors MUST NOT return {@code null} at this point, as this source is enabled.
96       */
97      protected abstract Map<String, String> doGetTrustedArtifactChecksums(
98              RepositorySystemSession session,
99              Artifact artifact,
100             ArtifactRepository artifactRepository,
101             List<ChecksumAlgorithmFactory> checksumAlgorithmFactories);
102 
103     /**
104      * Implementors may override this method and return {@link Writer} instance.
105      */
106     protected Writer doGetTrustedArtifactChecksumsWriter(RepositorySystemSession session) {
107         return null;
108     }
109 
110     /**
111      * Returns {@code true} if session configuration marks this instance as enabled.
112      * <p>
113      * Default value is {@code false}.
114      */
115     protected abstract boolean isEnabled(RepositorySystemSession session);
116 
117     /**
118      * Uses utility {@link DirectoryUtils#resolveDirectory(RepositorySystemSession, String, String, boolean)} to
119      * calculate (and maybe create) basedir for this implementation, never returns {@code null}. The returned
120      * {@link Path} may not exist, if invoked with {@code mayCreate} being {@code false}.
121      * <p>
122      * Default value is {@code ${LOCAL_REPOSITORY}/.checksums}.
123      *
124      * @return The {@link Path} of basedir, never {@code null}.
125      */
126     protected Path getBasedir(
127             RepositorySystemSession session, String defaultValue, String configPropKey, boolean mayCreate) {
128         try {
129             return DirectoryUtils.resolveDirectory(session, defaultValue, configPropKey, mayCreate);
130         } catch (IOException e) {
131             throw new UncheckedIOException(e);
132         }
133     }
134 }