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.Inject; 022import javax.inject.Named; 023import javax.inject.Singleton; 024 025import java.util.ArrayList; 026import java.util.Collections; 027import java.util.List; 028import java.util.Map; 029 030import org.eclipse.aether.RepositorySystemSession; 031import org.eclipse.aether.impl.RemoteRepositoryFilterManager; 032import org.eclipse.aether.impl.RepositoryConnectorProvider; 033import org.eclipse.aether.internal.impl.filter.FilteringRepositoryConnector; 034import org.eclipse.aether.repository.RemoteRepository; 035import org.eclipse.aether.spi.connector.RepositoryConnector; 036import org.eclipse.aether.spi.connector.RepositoryConnectorFactory; 037import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter; 038import org.eclipse.aether.transfer.NoRepositoryConnectorException; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042import static java.util.Objects.requireNonNull; 043 044/** 045 */ 046@Singleton 047@Named 048public class DefaultRepositoryConnectorProvider implements RepositoryConnectorProvider { 049 050 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRepositoryConnectorProvider.class); 051 052 private final Map<String, RepositoryConnectorFactory> connectorFactories; 053 054 private final RemoteRepositoryFilterManager remoteRepositoryFilterManager; 055 056 @Inject 057 public DefaultRepositoryConnectorProvider( 058 Map<String, RepositoryConnectorFactory> connectorFactories, 059 RemoteRepositoryFilterManager remoteRepositoryFilterManager) { 060 this.connectorFactories = Collections.unmodifiableMap(connectorFactories); 061 this.remoteRepositoryFilterManager = requireNonNull(remoteRepositoryFilterManager); 062 } 063 064 @Override 065 public RepositoryConnector newRepositoryConnector(RepositorySystemSession session, RemoteRepository repository) 066 throws NoRepositoryConnectorException { 067 requireNonNull(repository, "remote repository cannot be null"); 068 069 if (repository.isBlocked()) { 070 if (repository.getMirroredRepositories().isEmpty()) { 071 throw new NoRepositoryConnectorException(repository, "Blocked repository: " + repository); 072 } else { 073 throw new NoRepositoryConnectorException( 074 repository, "Blocked mirror for repositories: " + repository.getMirroredRepositories()); 075 } 076 } 077 078 PrioritizedComponents<RepositoryConnectorFactory> factories = PrioritizedComponents.reuseOrCreate( 079 session, RepositoryConnectorFactory.class, connectorFactories, RepositoryConnectorFactory::getPriority); 080 081 RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session); 082 List<NoRepositoryConnectorException> errors = new ArrayList<>(); 083 for (PrioritizedComponent<RepositoryConnectorFactory> factory : factories.getEnabled()) { 084 try { 085 RepositoryConnector connector = factory.getComponent().newInstance(session, repository); 086 087 if (LOGGER.isDebugEnabled()) { 088 StringBuilder buffer = new StringBuilder(256); 089 buffer.append("Using connector ") 090 .append(connector.getClass().getSimpleName()); 091 Utils.appendClassLoader(buffer, connector); 092 buffer.append(" with priority ").append(factory.getPriority()); 093 buffer.append(" for ").append(repository.getUrl()); 094 LOGGER.debug(buffer.toString()); 095 } 096 097 if (filter != null) { 098 return new FilteringRepositoryConnector(repository, connector, filter); 099 } else { 100 return connector; 101 } 102 } catch (NoRepositoryConnectorException e) { 103 // continue and try next factory 104 LOGGER.debug("Could not obtain connector factory for {}", repository, e); 105 errors.add(e); 106 } 107 } 108 109 StringBuilder buffer = new StringBuilder(256); 110 if (factories.isEmpty()) { 111 buffer.append("No connector factories available"); 112 } else { 113 buffer.append("Cannot access ").append(repository.getUrl()); 114 buffer.append(" with type ").append(repository.getContentType()); 115 buffer.append(" using the available connector factories: "); 116 factories.list(buffer); 117 } 118 119 // create exception: if one error, make it cause 120 NoRepositoryConnectorException ex = new NoRepositoryConnectorException( 121 repository, buffer.toString(), errors.size() == 1 ? errors.get(0) : null); 122 // if more errors, make them all suppressed 123 if (errors.size() > 1) { 124 errors.forEach(ex::addSuppressed); 125 } 126 throw ex; 127 } 128}