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.Collections;
27  import java.util.List;
28  import java.util.Map;
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.transfer.NoRepositoryConnectorException;
41  import org.slf4j.Logger;
42  import org.slf4j.LoggerFactory;
43  
44  import static java.util.Objects.requireNonNull;
45  
46  /**
47   */
48  @Singleton
49  @Named
50  public class DefaultRepositoryConnectorProvider implements RepositoryConnectorProvider {
51  
52      private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRepositoryConnectorProvider.class);
53  
54      private final Map<String, RepositoryConnectorFactory> connectorFactories;
55  
56      private final RemoteRepositoryFilterManager remoteRepositoryFilterManager;
57  
58      @Inject
59      public DefaultRepositoryConnectorProvider(
60              Map<String, RepositoryConnectorFactory> connectorFactories,
61              RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
62          this.connectorFactories = Collections.unmodifiableMap(connectorFactories);
63          this.remoteRepositoryFilterManager = requireNonNull(remoteRepositoryFilterManager);
64      }
65  
66      @Override
67      public RepositoryConnector newRepositoryConnector(RepositorySystemSession session, RemoteRepository repository)
68              throws NoRepositoryConnectorException {
69          requireNonNull(repository, "remote repository cannot be null");
70  
71          if (repository.isBlocked()) {
72              if (repository.getMirroredRepositories().isEmpty()) {
73                  throw new NoRepositoryConnectorException(repository, "Blocked repository: " + repository);
74              } else {
75                  throw new NoRepositoryConnectorException(
76                          repository, "Blocked mirror for repositories: " + repository.getMirroredRepositories());
77              }
78          }
79  
80          PrioritizedComponents<RepositoryConnectorFactory> factories = PrioritizedComponents.reuseOrCreate(
81                  session, connectorFactories, RepositoryConnectorFactory::getPriority);
82  
83          RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
84          List<NoRepositoryConnectorException> errors = new ArrayList<>();
85          for (PrioritizedComponent<RepositoryConnectorFactory> factory : factories.getEnabled()) {
86              try {
87                  RepositoryConnector connector = factory.getComponent().newInstance(session, repository);
88  
89                  if (LOGGER.isDebugEnabled()) {
90                      StringBuilder buffer = new StringBuilder(256);
91                      buffer.append("Using connector ")
92                              .append(connector.getClass().getSimpleName());
93                      Utils.appendClassLoader(buffer, connector);
94                      buffer.append(" with priority ").append(factory.getPriority());
95                      buffer.append(" for ").append(repository.getUrl());
96  
97                      Authentication auth = repository.getAuthentication();
98                      if (auth != null) {
99                          buffer.append(" with ").append(auth);
100                     }
101 
102                     Proxy proxy = repository.getProxy();
103                     if (proxy != null) {
104                         buffer.append(" via ")
105                                 .append(proxy.getHost())
106                                 .append(':')
107                                 .append(proxy.getPort());
108 
109                         auth = proxy.getAuthentication();
110                         if (auth != null) {
111                             buffer.append(" with ").append(auth);
112                         }
113                     }
114 
115                     LOGGER.debug(buffer.toString());
116                 }
117 
118                 if (filter != null) {
119                     return new FilteringRepositoryConnector(repository, connector, filter);
120                 } else {
121                     return connector;
122                 }
123             } catch (NoRepositoryConnectorException e) {
124                 // continue and try next factory
125                 errors.add(e);
126             }
127         }
128         if (LOGGER.isDebugEnabled() && errors.size() > 1) {
129             for (Exception e : errors) {
130                 LOGGER.debug("Could not obtain connector factory for {}", repository, e);
131             }
132         }
133 
134         StringBuilder buffer = new StringBuilder(256);
135         if (factories.isEmpty()) {
136             buffer.append("No connector factories available");
137         } else {
138             buffer.append("Cannot access ").append(repository.getUrl());
139             buffer.append(" with type ").append(repository.getContentType());
140             buffer.append(" using the available connector factories: ");
141             factories.list(buffer);
142         }
143 
144         throw new NoRepositoryConnectorException(
145                 repository, buffer.toString(), errors.size() == 1 ? errors.get(0) : null);
146     }
147 }