View Javadoc
1   package org.eclipse.aether.internal.impl;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.List;
25  import static java.util.Objects.requireNonNull;
26  import java.util.Set;
27  
28  import javax.inject.Inject;
29  import javax.inject.Named;
30  
31  import org.eclipse.aether.RepositorySystemSession;
32  import org.eclipse.aether.repository.RemoteRepository;
33  import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
34  import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
35  import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
36  import org.eclipse.aether.spi.locator.Service;
37  import org.eclipse.aether.spi.locator.ServiceLocator;
38  import org.eclipse.aether.spi.log.Logger;
39  import org.eclipse.aether.spi.log.LoggerFactory;
40  import org.eclipse.aether.spi.log.NullLoggerFactory;
41  import org.eclipse.aether.transfer.NoRepositoryLayoutException;
42  
43  /**
44   */
45  @Named
46  public final class DefaultRepositoryLayoutProvider
47      implements RepositoryLayoutProvider, Service
48  {
49  
50      private Logger logger = NullLoggerFactory.LOGGER;
51  
52      private Collection<RepositoryLayoutFactory> factories = new ArrayList<RepositoryLayoutFactory>();
53  
54      public DefaultRepositoryLayoutProvider()
55      {
56          // enables default constructor
57      }
58  
59      @Inject
60      DefaultRepositoryLayoutProvider( Set<RepositoryLayoutFactory> layoutFactories, LoggerFactory loggerFactory )
61      {
62          setLoggerFactory( loggerFactory );
63          setRepositoryLayoutFactories( layoutFactories );
64      }
65  
66      public void initService( ServiceLocator locator )
67      {
68          setLoggerFactory( locator.getService( LoggerFactory.class ) );
69          setRepositoryLayoutFactories( locator.getServices( RepositoryLayoutFactory.class ) );
70      }
71  
72      public DefaultRepositoryLayoutProvider setLoggerFactory( LoggerFactory loggerFactory )
73      {
74          this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
75          return this;
76      }
77  
78      public DefaultRepositoryLayoutProvider addRepositoryLayoutFactory( RepositoryLayoutFactory factory )
79      {
80          factories.add( requireNonNull( factory, "layout factory cannot be null" ) );
81          return this;
82      }
83  
84      public DefaultRepositoryLayoutProvider setRepositoryLayoutFactories( Collection<RepositoryLayoutFactory> factories )
85      {
86          if ( factories == null )
87          {
88              this.factories = new ArrayList<RepositoryLayoutFactory>();
89          }
90          else
91          {
92              this.factories = factories;
93          }
94          return this;
95      }
96  
97      public RepositoryLayout newRepositoryLayout( RepositorySystemSession session, RemoteRepository repository )
98          throws NoRepositoryLayoutException
99      {
100         requireNonNull( repository, "remote repository cannot be null" );
101 
102         PrioritizedComponents<RepositoryLayoutFactory> factories =
103             new PrioritizedComponents<RepositoryLayoutFactory>( session );
104         for ( RepositoryLayoutFactory factory : this.factories )
105         {
106             factories.add( factory, factory.getPriority() );
107         }
108 
109         List<NoRepositoryLayoutException> errors = new ArrayList<NoRepositoryLayoutException>();
110         for ( PrioritizedComponent<RepositoryLayoutFactory> factory : factories.getEnabled() )
111         {
112             try
113             {
114                 RepositoryLayout layout = factory.getComponent().newInstance( session, repository );
115                 return layout;
116             }
117             catch ( NoRepositoryLayoutException e )
118             {
119                 // continue and try next factory
120                 errors.add( e );
121             }
122         }
123         if ( logger.isDebugEnabled() && errors.size() > 1 )
124         {
125             String msg = "Could not obtain layout factory for " + repository;
126             for ( Exception e : errors )
127             {
128                 logger.debug( msg, e );
129             }
130         }
131 
132         StringBuilder buffer = new StringBuilder( 256 );
133         if ( factories.isEmpty() )
134         {
135             buffer.append( "No layout factories registered" );
136         }
137         else
138         {
139             buffer.append( "Cannot access " ).append( repository.getUrl() );
140             buffer.append( " with type " ).append( repository.getContentType() );
141             buffer.append( " using the available layout factories: " );
142             factories.list( buffer );
143         }
144 
145         throw new NoRepositoryLayoutException( repository, buffer.toString(), errors.size() == 1 ? errors.get( 0 )
146                         : null );
147     }
148 
149 }