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      public DefaultRepositoryConnectorProvider() {
61          // enables default constructor
62      }
63  
64      @Inject
65      DefaultRepositoryConnectorProvider(
66              Set<RepositoryConnectorFactory> connectorFactories,
67              RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
68          setRepositoryConnectorFactories(connectorFactories);
69          setRemoteRepositoryFilterManager(remoteRepositoryFilterManager);
70      }
71  
72      public void initService(ServiceLocator locator) {
73          setRepositoryConnectorFactories(locator.getServices(RepositoryConnectorFactory.class));
74          setRemoteRepositoryFilterManager(locator.getService(RemoteRepositoryFilterManager.class));
75      }
76  
77      public DefaultRepositoryConnectorProvider addRepositoryConnectorFactory(RepositoryConnectorFactory factory) {
78          connectorFactories.add(requireNonNull(factory, "repository connector factory cannot be null"));
79          return this;
80      }
81  
82      public DefaultRepositoryConnectorProvider setRepositoryConnectorFactories(
83              Collection<RepositoryConnectorFactory> factories) {
84          if (factories == null) {
85              this.connectorFactories = new ArrayList<>();
86          } else {
87              this.connectorFactories = factories;
88          }
89          return this;
90      }
91  
92      public DefaultRepositoryConnectorProvider setRemoteRepositoryFilterManager(
93              RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
94          this.remoteRepositoryFilterManager = requireNonNull(remoteRepositoryFilterManager);
95          return this;
96      }
97  
98      public RepositoryConnector newRepositoryConnector(RepositorySystemSession session, RemoteRepository repository)
99              throws NoRepositoryConnectorException {
100         requireNonNull(repository, "remote repository cannot be null");
101 
102         if (repository.isBlocked()) {
103             if (repository.getMirroredRepositories().isEmpty()) {
104                 throw new NoRepositoryConnectorException(repository, "Blocked repository: " + repository);
105             } else {
106                 throw new NoRepositoryConnectorException(
107                         repository, "Blocked mirror for repositories: " + repository.getMirroredRepositories());
108             }
109         }
110 
111         RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
112 
113         PrioritizedComponents<RepositoryConnectorFactory> factories = new PrioritizedComponents<>(session);
114         for (RepositoryConnectorFactory factory : this.connectorFactories) {
115             factories.add(factory, factory.getPriority());
116         }
117 
118         List<NoRepositoryConnectorException> errors = new ArrayList<>();
119         for (PrioritizedComponent<RepositoryConnectorFactory> factory : factories.getEnabled()) {
120             try {
121                 RepositoryConnector connector = factory.getComponent().newInstance(session, repository);
122 
123                 if (LOGGER.isDebugEnabled()) {
124                     StringBuilder buffer = new StringBuilder(256);
125                     buffer.append("Using connector ")
126                             .append(connector.getClass().getSimpleName());
127                     Utils.appendClassLoader(buffer, connector);
128                     buffer.append(" with priority ").append(factory.getPriority());
129                     buffer.append(" for ").append(repository.getUrl());
130 
131                     Authentication auth = repository.getAuthentication();
132                     if (auth != null) {
133                         buffer.append(" with ").append(auth);
134                     }
135 
136                     Proxy proxy = repository.getProxy();
137                     if (proxy != null) {
138                         buffer.append(" via ")
139                                 .append(proxy.getHost())
140                                 .append(':')
141                                 .append(proxy.getPort());
142 
143                         auth = proxy.getAuthentication();
144                         if (auth != null) {
145                             buffer.append(" with ").append(auth);
146                         }
147                     }
148 
149                     LOGGER.debug(buffer.toString());
150                 }
151 
152                 if (filter != null) {
153                     return new FilteringRepositoryConnector(repository, connector, filter);
154                 } else {
155                     return connector;
156                 }
157             } catch (NoRepositoryConnectorException e) {
158                 // continue and try next factory
159                 errors.add(e);
160             }
161         }
162         if (LOGGER.isDebugEnabled() && errors.size() > 1) {
163             for (Exception e : errors) {
164                 LOGGER.debug("Could not obtain connector factory for {}", repository, e);
165             }
166         }
167 
168         StringBuilder buffer = new StringBuilder(256);
169         if (factories.isEmpty()) {
170             buffer.append("No connector factories available");
171         } else {
172             buffer.append("Cannot access ").append(repository.getUrl());
173             buffer.append(" with type ").append(repository.getContentType());
174             buffer.append(" using the available connector factories: ");
175             factories.list(buffer);
176         }
177 
178         throw new NoRepositoryConnectorException(
179                 repository, buffer.toString(), errors.size() == 1 ? errors.get(0) : null);
180     }
181 }