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; 020 021import javax.inject.Named; 022import javax.inject.Singleton; 023 024import java.util.concurrent.ConcurrentHashMap; 025import java.util.concurrent.ConcurrentMap; 026 027import org.eclipse.aether.ConfigurationProperties; 028import org.eclipse.aether.Keys; 029import org.eclipse.aether.RepositorySystemSession; 030import org.eclipse.aether.repository.RemoteRepository; 031import org.eclipse.aether.repository.RepositoryKeyFunction; 032import org.eclipse.aether.spi.remoterepo.RepositoryKeyFunctionFactory; 033import org.eclipse.aether.util.ConfigUtils; 034import org.eclipse.aether.util.repository.RepositoryIdHelper; 035 036import static java.util.Objects.requireNonNull; 037 038@Singleton 039@Named 040public class DefaultRepositoryKeyFunctionFactory implements RepositoryKeyFunctionFactory { 041 /** 042 * Returns system-wide repository key function. 043 * 044 * @since 2.0.14 045 * @see #repositoryKeyFunction(Class, RepositorySystemSession, String, String) 046 */ 047 @Override 048 public RepositoryKeyFunction systemRepositoryKeyFunction(RepositorySystemSession session) { 049 return repositoryKeyFunction( 050 DefaultRepositoryKeyFunctionFactory.class, 051 session, 052 ConfigurationProperties.DEFAULT_REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION, 053 ConfigurationProperties.REPOSITORY_SYSTEM_REPOSITORY_KEY_FUNCTION); 054 } 055 056 /** 057 * Method that based on configuration returns the "repository key function". The returned function will be session 058 * cached if session is equipped with cache, otherwise it will be non cached. Method never returns {@code null}. 059 * Only the {@code configurationKey} parameter may be {@code null} in which case no configuration lookup happens 060 * but the {@code defaultValue} is directly used instead. 061 * 062 * @since 2.0.14 063 */ 064 @SuppressWarnings("unchecked") 065 @Override 066 public RepositoryKeyFunction repositoryKeyFunction( 067 Class<?> owner, RepositorySystemSession session, String defaultValue, String configurationKey) { 068 requireNonNull(session); 069 requireNonNull(defaultValue); 070 final RepositoryKeyFunction repositoryKeyFunction = RepositoryIdHelper.getRepositoryKeyFunction( 071 configurationKey != null 072 ? ConfigUtils.getString(session, defaultValue, configurationKey) 073 : defaultValue); 074 if (session.getCache() != null) { 075 // both are expensive methods; cache it in session (repo -> context -> ID) 076 return (repository, context) -> ((ConcurrentMap<RemoteRepository, ConcurrentMap<String, String>>) 077 session.getCache() 078 .computeIfAbsent( 079 session, Keys.of(owner, "repositoryKeyFunction"), ConcurrentHashMap::new)) 080 .computeIfAbsent(repository, k1 -> new ConcurrentHashMap<>()) 081 .computeIfAbsent( 082 context == null ? "" : context, k2 -> repositoryKeyFunction.apply(repository, context)); 083 } else { 084 return repositoryKeyFunction; 085 } 086 } 087}