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