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.RemoteRepository;
35  import org.eclipse.aether.spi.connector.RepositoryConnector;
36  import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
37  import org.eclipse.aether.spi.connector.filter.RemoteRepositoryFilter;
38  import org.eclipse.aether.transfer.NoRepositoryConnectorException;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  import static java.util.Objects.requireNonNull;
43  
44  /**
45   */
46  @Singleton
47  @Named
48  public class DefaultRepositoryConnectorProvider implements RepositoryConnectorProvider {
49  
50      private static final Logger LOGGER = LoggerFactory.getLogger(DefaultRepositoryConnectorProvider.class);
51  
52      private final Map<String, RepositoryConnectorFactory> connectorFactories;
53  
54      private final RemoteRepositoryFilterManager remoteRepositoryFilterManager;
55  
56      @Inject
57      public DefaultRepositoryConnectorProvider(
58              Map<String, RepositoryConnectorFactory> connectorFactories,
59              RemoteRepositoryFilterManager remoteRepositoryFilterManager) {
60          this.connectorFactories = Collections.unmodifiableMap(connectorFactories);
61          this.remoteRepositoryFilterManager = requireNonNull(remoteRepositoryFilterManager);
62      }
63  
64      @Override
65      public RepositoryConnector newRepositoryConnector(RepositorySystemSession session, RemoteRepository repository)
66              throws NoRepositoryConnectorException {
67          requireNonNull(repository, "remote repository cannot be null");
68  
69          if (repository.isBlocked()) {
70              if (repository.getMirroredRepositories().isEmpty()) {
71                  throw new NoRepositoryConnectorException(repository, "Blocked repository: " + repository);
72              } else {
73                  throw new NoRepositoryConnectorException(
74                          repository, "Blocked mirror for repositories: " + repository.getMirroredRepositories());
75              }
76          }
77  
78          PrioritizedComponents<RepositoryConnectorFactory> factories = PrioritizedComponents.reuseOrCreate(
79                  session, RepositoryConnectorFactory.class, connectorFactories, RepositoryConnectorFactory::getPriority);
80  
81          RemoteRepositoryFilter filter = remoteRepositoryFilterManager.getRemoteRepositoryFilter(session);
82          List<NoRepositoryConnectorException> errors = new ArrayList<>();
83          for (PrioritizedComponent<RepositoryConnectorFactory> factory : factories.getEnabled()) {
84              try {
85                  RepositoryConnector connector = factory.getComponent().newInstance(session, repository);
86  
87                  if (LOGGER.isDebugEnabled()) {
88                      StringBuilder buffer = new StringBuilder(256);
89                      buffer.append("Using connector ")
90                              .append(connector.getClass().getSimpleName());
91                      Utils.appendClassLoader(buffer, connector);
92                      buffer.append(" with priority ").append(factory.getPriority());
93                      buffer.append(" for ").append(repository.getUrl());
94                      LOGGER.debug(buffer.toString());
95                  }
96  
97                  if (filter != null) {
98                      return new FilteringRepositoryConnector(repository, connector, filter);
99                  } 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 }