001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.internal.impl.filter; 020 021import java.io.IOException; 022import java.io.UncheckedIOException; 023import java.nio.file.Path; 024import java.util.ArrayList; 025import java.util.List; 026 027import org.eclipse.aether.ConfigurationProperties; 028import org.eclipse.aether.RepositorySystemSession; 029import org.eclipse.aether.repository.RemoteRepository; 030import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter; 031import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilterSource; 032import org.eclipse.aether.spi.remoterepo.RepositoryKeyFunctionFactory; 033import org.eclipse.aether.util.DirectoryUtils; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037import static java.util.Objects.requireNonNull; 038 039/** 040 * Support class for {@link RemoteRepositoryFilterSource} implementations. 041 * <p> 042 * Support class for implementing {@link RemoteRepositoryFilterSource}. It implements basic support 043 * like optional "basedir" calculation, handling of "enabled" flag. 044 * <p> 045 * The configuration keys supported: 046 * <ul> 047 * <li><pre>aether.remoteRepositoryFilter.${id}.enabled</pre> (boolean) must be explicitly set to "true" 048 * to become enabled</li> 049 * <li><pre>aether.remoteRepositoryFilter.${id}.basedir</pre> (string, path) directory from where implementation 050 * can use files. If unset, default value is ".remoteRepositoryFilters/${id}" and is resolved from local 051 * repository basedir.</li> 052 * </ul> 053 * 054 * @since 1.9.0 055 */ 056public abstract class RemoteRepositoryFilterSourceSupport implements RemoteRepositoryFilterSource { 057 protected static final String CONFIG_PROPS_PREFIX = 058 ConfigurationProperties.PREFIX_AETHER + "remoteRepositoryFilter."; 059 060 protected final Logger logger = LoggerFactory.getLogger(getClass()); 061 062 private final RepositoryKeyFunctionFactory repositoryKeyFunctionFactory; 063 064 protected RemoteRepositoryFilterSourceSupport(RepositoryKeyFunctionFactory repositoryKeyFunctionFactory) { 065 this.repositoryKeyFunctionFactory = requireNonNull(repositoryKeyFunctionFactory); 066 } 067 068 /** 069 * Returns {@code true} if session configuration contains this name set to {@code true}. 070 * <p> 071 * Default is {@code true}. 072 */ 073 protected abstract boolean isEnabled(RepositorySystemSession session); 074 075 /** 076 * Uses common {@link DirectoryUtils#resolveDirectory(RepositorySystemSession, String, String, boolean)} to 077 * calculate (and maybe create) basedir for this implementation, never returns {@code null}. The returned 078 * {@link Path} may not exists, if invoked with {@code mayCreate} being {@code false}. 079 * <p> 080 * Default value is {@code ${LOCAL_REPOSITORY}/.checksums}. 081 * 082 * @return The {@link Path} of basedir, never {@code null}. 083 */ 084 protected Path getBasedir( 085 RepositorySystemSession session, String defaultValue, String configPropKey, boolean mayCreate) { 086 try { 087 return DirectoryUtils.resolveDirectory(session, defaultValue, configPropKey, mayCreate); 088 } catch (IOException e) { 089 throw new UncheckedIOException(e); 090 } 091 } 092 093 /** 094 * We use remote repositories as keys, so normalize them. 095 * 096 * @since 2.0.14 097 * @see RemoteRepository#toBareRemoteRepository() 098 */ 099 protected RemoteRepository normalizeRemoteRepository( 100 RepositorySystemSession session, RemoteRepository remoteRepository) { 101 return remoteRepository.toBareRemoteRepository(); 102 } 103 104 /** 105 * Returns repository keys to be used on file system layout for user provided files. They are ordered as 106 * "most specific" (using {@link RepositoryKeyFunctionFactory#trackingRepositoryKeyFunction(RepositorySystemSession)}) 107 * to simple "id based" one. This allows user to keep using plain ID, but also to provide very narrowly targeted 108 * input files, when needed. 109 * 110 * @since 2.0.14 111 */ 112 protected List<String> repositoryKeys(RepositorySystemSession session, RemoteRepository repository) { 113 ArrayList<String> keys = new ArrayList<>(); 114 keys.add(repositoryKeyFunctionFactory 115 .trackingRepositoryKeyFunction(session) 116 .apply(repository, null)); 117 keys.add(repositoryKeyFunctionFactory 118 .systemRepositoryKeyFunction(session) 119 .apply(repository, null)); 120 return keys; 121 } 122 123 /** 124 * Simple {@link RemoteRepositoryFilter.Result} immutable implementation. 125 */ 126 private static class SimpleResult implements RemoteRepositoryFilter.Result { 127 private final boolean accepted; 128 129 private final String reasoning; 130 131 private SimpleResult(boolean accepted, String reasoning) { 132 this.accepted = accepted; 133 this.reasoning = requireNonNull(reasoning); 134 } 135 136 @Override 137 public boolean isAccepted() { 138 return accepted; 139 } 140 141 @Override 142 public String reasoning() { 143 return reasoning; 144 } 145 } 146 147 /** 148 * Visible for testing. 149 */ 150 static RemoteRepositoryFilter.Result result(boolean accepted, String name, String message) { 151 return new SimpleResult(accepted, name + ": " + message); 152 } 153}