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.Collections;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.eclipse.aether.ConfigurationProperties;
28  import org.eclipse.aether.RepositorySystemSession;
29  import org.eclipse.aether.util.ConfigUtils;
30  
31  /**
32   * Helps to sort pluggable components by their priority.
33   */
34  final class PrioritizedComponents<T>
35  {
36  
37      private static final String FACTORY_SUFFIX = "Factory";
38  
39      private final Map<?, ?> configProps;
40  
41      private final boolean useInsertionOrder;
42  
43      private final List<PrioritizedComponent<T>> components;
44  
45      private int firstDisabled;
46  
47      PrioritizedComponents( RepositorySystemSession session )
48      {
49          this( session.getConfigProperties() );
50      }
51  
52      PrioritizedComponents( Map<?, ?> configurationProperties )
53      {
54          configProps = configurationProperties;
55          useInsertionOrder =
56              ConfigUtils.getBoolean( configProps, ConfigurationProperties.DEFAULT_IMPLICIT_PRIORITIES,
57                                      ConfigurationProperties.IMPLICIT_PRIORITIES );
58          components = new ArrayList<>();
59          firstDisabled = 0;
60      }
61  
62      public void add( T component, float priority )
63      {
64          Class<?> type = getImplClass( component );
65          int index = components.size();
66          priority = useInsertionOrder ? -index : ConfigUtils.getFloat( configProps, priority, getConfigKeys( type ) );
67          PrioritizedComponent<T> pc = new PrioritizedComponent<>( component, type, priority, index );
68  
69          if ( !useInsertionOrder )
70          {
71              index = Collections.binarySearch( components, pc );
72              if ( index < 0 )
73              {
74                  index = -index - 1;
75              }
76              else
77              {
78                  index++;
79              }
80          }
81          components.add( index, pc );
82  
83          if ( index <= firstDisabled && !pc.isDisabled() )
84          {
85              firstDisabled++;
86          }
87      }
88  
89      private static Class<?> getImplClass( Object component )
90      {
91          Class<?> type = component.getClass();
92          // detect and ignore CGLIB-based proxy classes employed by Guice for AOP (cf. BytecodeGen.newEnhancer)
93          int idx = type.getName().indexOf( "$$" );
94          if ( idx >= 0 )
95          {
96              Class<?> base = type.getSuperclass();
97              if ( base != null && idx == base.getName().length() && type.getName().startsWith( base.getName() ) )
98              {
99                  type = base;
100             }
101         }
102         return type;
103     }
104 
105     static String[] getConfigKeys( Class<?> type )
106     {
107         List<String> keys = new ArrayList<>();
108         keys.add( ConfigurationProperties.PREFIX_PRIORITY + type.getName() );
109         String sn = type.getSimpleName();
110         keys.add( ConfigurationProperties.PREFIX_PRIORITY + sn );
111         if ( sn.endsWith( FACTORY_SUFFIX ) )
112         {
113             keys.add(
114               ConfigurationProperties.PREFIX_PRIORITY + sn.substring( 0, sn.length() - FACTORY_SUFFIX.length() ) );
115         }
116         return keys.toArray( new String[keys.size()] );
117     }
118 
119     public boolean isEmpty()
120     {
121         return components.isEmpty();
122     }
123 
124     public List<PrioritizedComponent<T>> getAll()
125     {
126         return components;
127     }
128 
129     public List<PrioritizedComponent<T>> getEnabled()
130     {
131         return components.subList( 0, firstDisabled );
132     }
133 
134     public void list( StringBuilder buffer )
135     {
136         int i = 0;
137         for ( PrioritizedComponent<?> component : components )
138         {
139             if ( i++ > 0 )
140             {
141                 buffer.append( ", " );
142             }
143             buffer.append( component.getType().getSimpleName() );
144             if ( component.isDisabled() )
145             {
146                 buffer.append( " (disabled)" );
147             }
148         }
149     }
150 
151     @Override
152     public String toString()
153     {
154         return components.toString();
155     }
156 
157 }