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 java.util.Set;
26  
27  import javax.inject.Inject;
28  import javax.inject.Named;
29  
30  import org.eclipse.aether.RepositorySystemSession;
31  import org.eclipse.aether.repository.RemoteRepository;
32  import org.eclipse.aether.spi.connector.layout.RepositoryLayout;
33  import org.eclipse.aether.spi.connector.layout.RepositoryLayoutFactory;
34  import org.eclipse.aether.spi.connector.layout.RepositoryLayoutProvider;
35  import org.eclipse.aether.spi.locator.Service;
36  import org.eclipse.aether.spi.locator.ServiceLocator;
37  import org.eclipse.aether.spi.log.Logger;
38  import org.eclipse.aether.spi.log.LoggerFactory;
39  import org.eclipse.aether.spi.log.NullLoggerFactory;
40  import org.eclipse.aether.transfer.NoRepositoryLayoutException;
41  
42  /**
43   */
44  @Named
45  public final class DefaultRepositoryLayoutProvider
46      implements RepositoryLayoutProvider, Service
47  {
48  
49      private Logger logger = NullLoggerFactory.LOGGER;
50  
51      private Collection<RepositoryLayoutFactory> factories = new ArrayList<RepositoryLayoutFactory>();
52  
53      public DefaultRepositoryLayoutProvider()
54      {
55          // enables default constructor
56      }
57  
58      @Inject
59      DefaultRepositoryLayoutProvider( Set<RepositoryLayoutFactory> layoutFactories, LoggerFactory loggerFactory )
60      {
61          setLoggerFactory( loggerFactory );
62          setRepositoryLayoutFactories( layoutFactories );
63      }
64  
65      public void initService( ServiceLocator locator )
66      {
67          setLoggerFactory( locator.getService( LoggerFactory.class ) );
68          setRepositoryLayoutFactories( locator.getServices( RepositoryLayoutFactory.class ) );
69      }
70  
71      public DefaultRepositoryLayoutProvider setLoggerFactory( LoggerFactory loggerFactory )
72      {
73          this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() );
74          return this;
75      }
76  
77      public DefaultRepositoryLayoutProvider addRepositoryLayoutFactory( RepositoryLayoutFactory factory )
78      {
79          if ( factory == null )
80          {
81              throw new IllegalArgumentException( "layout factory has not been specified" );
82          }
83          factories.add( factory );
84          return this;
85      }
86  
87      public DefaultRepositoryLayoutProvider setRepositoryLayoutFactories( Collection<RepositoryLayoutFactory> factories )
88      {
89          if ( factories == null )
90          {
91              this.factories = new ArrayList<RepositoryLayoutFactory>();
92          }
93          else
94          {
95              this.factories = factories;
96          }
97          return this;
98      }
99  
100     public RepositoryLayout newRepositoryLayout( RepositorySystemSession session, RemoteRepository repository )
101         throws NoRepositoryLayoutException
102     {
103         if ( repository == null )
104         {
105             throw new IllegalArgumentException( "remote repository has not been specified" );
106         }
107 
108         PrioritizedComponents<RepositoryLayoutFactory> factories =
109             new PrioritizedComponents<RepositoryLayoutFactory>( session );
110         for ( RepositoryLayoutFactory factory : this.factories )
111         {
112             factories.add( factory, factory.getPriority() );
113         }
114 
115         List<NoRepositoryLayoutException> errors = new ArrayList<NoRepositoryLayoutException>();
116         for ( PrioritizedComponent<RepositoryLayoutFactory> factory : factories.getEnabled() )
117         {
118             try
119             {
120                 RepositoryLayout layout = factory.getComponent().newInstance( session, repository );
121                 return layout;
122             }
123             catch ( NoRepositoryLayoutException e )
124             {
125                 // continue and try next factory
126                 errors.add( e );
127             }
128         }
129         if ( logger.isDebugEnabled() && errors.size() > 1 )
130         {
131             String msg = "Could not obtain layout factory for " + repository;
132             for ( Exception e : errors )
133             {
134                 logger.debug( msg, e );
135             }
136         }
137 
138         StringBuilder buffer = new StringBuilder( 256 );
139         if ( factories.isEmpty() )
140         {
141             buffer.append( "No layout factories registered" );
142         }
143         else
144         {
145             buffer.append( "Cannot access " ).append( repository.getUrl() );
146             buffer.append( " with type " ).append( repository.getContentType() );
147             buffer.append( " using the available layout factories: " );
148             factories.list( buffer );
149         }
150 
151         throw new NoRepositoryLayoutException( repository, buffer.toString(), errors.size() == 1 ? errors.get( 0 )
152                         : null );
153     }
154 
155 }