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;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.List;
28  import java.util.Set;
29  
30  import org.eclipse.aether.RepositorySystemSession;
31  import org.eclipse.aether.impl.RemoteRepositoryFilterManager;
32  import org.eclipse.aether.impl.RepositoryConnectorProvider;
33  import org.eclipse.aether.internal.impl.filter.FilteringRepositoryConnector;
34  import org.eclipse.aether.repository.Authentication;
35  import org.eclipse.aether.repository.Proxy;
36  import org.eclipse.aether.repository.RemoteRepository;
37  import org.eclipse.aether.spi.connector.RepositoryConnector;
38  import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
39  import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
40  import org.eclipse.aether.spi.locator.Service;
41  import org.eclipse.aether.spi.locator.ServiceLocator;
42  import org.eclipse.aether.transfer.NoRepositoryConnectorException;
43  import org.slf4j.Logger;
44  import org.slf4j.LoggerFactory;
45  
46  import static java.util.Objects.requireNonNull;
47  
48  /**
49   */
50  @Singleton
51  @Named
52  public class DefaultRepositoryConnectorProvider implements RepositoryConnectorProvider, Service {
53  
54      private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRepositoryConnectorProvider.class);
55  
56      private Collection<RepositoryConnectorFactory> connectorFactories = new ArrayList<>();
57  
58      private RemoteRepositoryFilterManager remoteRepositoryFilterManager;
59  
60      @Deprecated
61      public DefaultRepositoryConnectorProvider() {
62          // enables default constructor
63      }
64  
65      @Inject
66      public DefaultRepositoryConnectorProvider(
67              Set<RepositoryConnectorFactory> connectorFactories,
68              RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
69          setRepositoryConnectorFactories(connectorFactories);
70          setRemoteRepositoryFilterManager(remoteRepositoryFilterManager);
71      }
72  
73      public void initService(ServiceLocator locator) {
74          setRepositoryConnectorFactories(locator.getServices(RepositoryConnectorFactory.class));
75          setRemoteRepositoryFilterManager(locator.getService(RemoteRepositoryFilterManager.class));
76      }
77  
78      public DefaultRepositoryConnectorProvider addRepositoryConnectorFactory(RepositoryConnectorFactory factory) {
79          connectorFactories.add(requireNonNull(factory, "repository connector factory cannot be null"));
80          return this;
81      }
82  
83      public DefaultRepositoryConnectorProvider setRepositoryConnectorFactories(
84              Collection<RepositoryConnectorFactory> factories) {
85          if (factories == null) {
86              this.connectorFactories = new ArrayList<>();
87          } else {
88              this.connectorFactories = factories;
89          }
90          return this;
91      }
92  
93      public DefaultRepositoryConnectorProvider setRemoteRepositoryFilterManager(
94              RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
95          this.remoteRepositoryFilterManager = requireNonNull(remoteRepositoryFilterManager);
96          return this;
97      }
98  
99      public RepositoryConnector newRepositoryConnector(RepositorySystemSession session, RemoteRepository repository)
100             throws NoRepositoryConnectorException {
101         requireNonNull(repository, "remote repository cannot be null");
102 
103         if (repository.isBlocked()) {
104             if (repository.getMirroredRepositories().isEmpty()) {
105                 throw new NoRepositoryConnectorException(repository, "Blocked repository: " + repository);
106             } else {
107                 throw new NoRepositoryConnectorException(
108                         repository, "Blocked mirror for repositories: " + repository.getMirroredRepositories());
109             }
110         }
111 
112         RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
113 
114         PrioritizedComponents<RepositoryConnectorFactory> factories = new PrioritizedComponents<>(session);
115         for (RepositoryConnectorFactory factory : this.connectorFactories) {
116             factories.add(factory, factory.getPriority());
117         }
118 
119         List<NoRepositoryConnectorException> errors = new ArrayList<>();
120         for (PrioritizedComponent<RepositoryConnectorFactory> factory : factories.getEnabled()) {
121             try {
122                 RepositoryConnector connector = factory.getComponent().newInstance(session, repository);
123 
124                 if (LOGGER.isDebugEnabled()) {
125                     StringBuilder buffer = new StringBuilder(256);
126                     buffer.append("Using connector ")
127                             .append(connector.getClass().getSimpleName());
128                     Utils.appendClassLoader(buffer, connector);
129                     buffer.append(" with priority ").append(factory.getPriority());
130                     buffer.append(" for ").append(repository.getUrl());
131 
132                     Authentication auth = repository.getAuthentication();
133                     if (auth != null) {
134                         buffer.append(" with ").append(auth);
135                     }
136 
137                     Proxy proxy = repository.getProxy();
138                     if (proxy != null) {
139                         buffer.append(" via ")
140                                 .append(proxy.getHost())
141                                 .append(':')
142                                 .append(proxy.getPort());
143 
144                         auth = proxy.getAuthentication();
145                         if (auth != null) {
146                             buffer.append(" with ").append(auth);
147                         }
148                     }
149 
150                     LOGGER.debug(buffer.toString());
151                 }
152 
153                 if (filter != null) {
154                     return new FilteringRepositoryConnector(repository, connector, filter);
155                 } else {
156                     return connector;
157                 }
158             } catch (NoRepositoryConnectorException e) {
159                 // continue and try next factory
160                 errors.add(e);
161             }
162         }
163         if (LOGGER.isDebugEnabled() && errors.size() > 1) {
164             for (Exception e : errors) {
165                 LOGGER.debug("Could not obtain connector factory for {}", repository, e);
166             }
167         }
168 
169         StringBuilder buffer = new StringBuilder(256);
170         if (factories.isEmpty()) {
171             buffer.append("No connector factories available");
172         } else {
173             buffer.append("Cannot access ").append(repository.getUrl());
174             buffer.append(" with type ").append(repository.getContentType());
175             buffer.append(" using the available connector factories: ");
176             factories.list(buffer);
177         }
178 
179         throw new NoRepositoryConnectorException(
180                 repository, buffer.toString(), errors.size() == 1 ? errors.get(0) : null);
181     }
182 }