1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.aether.internal.impl;
20
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.function.Function;
26
27 import org.eclipse.aether.ConfigurationProperties;
28 import org.eclipse.aether.RepositorySystemSession;
29 import org.eclipse.aether.util.ConfigUtils;
30
31
32
33
34
35
36 public final class PrioritizedComponents<T> {
37
38
39
40
41
42
43
44
45
46
47
48 @SuppressWarnings("unchecked")
49 public static <C> PrioritizedComponents<C> reuseOrCreate(
50 RepositorySystemSession session,
51 Class<C> discriminator,
52 Map<String, C> components,
53 Function<C, Float> priorityFunction) {
54 boolean cached = ConfigUtils.getBoolean(
55 session, ConfigurationProperties.DEFAULT_CACHED_PRIORITIES, ConfigurationProperties.CACHED_PRIORITIES);
56 if (cached) {
57 String key = PrioritizedComponents.class.getName() + ".pc." + discriminator.getName();
58 return (PrioritizedComponents<C>)
59 session.getData().computeIfAbsent(key, () -> create(session, components, priorityFunction));
60 } else {
61 return create(session, components, priorityFunction);
62 }
63 }
64
65 private static <C> PrioritizedComponents<C> create(
66 RepositorySystemSession session, Map<String, C> components, Function<C, Float> priorityFunction) {
67 PrioritizedComponents<C> newInstance = new PrioritizedComponents<>(session);
68 components.values().forEach(c -> newInstance.add(c, priorityFunction.apply(c)));
69 return newInstance;
70 }
71
72 private static final String FACTORY_SUFFIX = "Factory";
73
74 private final Map<?, ?> configProps;
75
76 private final boolean useInsertionOrder;
77
78 private final List<PrioritizedComponent<T>> components;
79
80 private int firstDisabled;
81
82 PrioritizedComponents(RepositorySystemSession session) {
83 this(session.getConfigProperties());
84 }
85
86 PrioritizedComponents(Map<?, ?> configurationProperties) {
87 configProps = configurationProperties;
88 useInsertionOrder = ConfigUtils.getBoolean(
89 configProps,
90 ConfigurationProperties.DEFAULT_IMPLICIT_PRIORITIES,
91 ConfigurationProperties.IMPLICIT_PRIORITIES);
92 components = new ArrayList<>();
93 firstDisabled = 0;
94 }
95
96 public void add(T component, float priority) {
97 Class<?> type = getImplClass(component);
98 int index = components.size();
99 priority = useInsertionOrder ? -index : ConfigUtils.getFloat(configProps, priority, getConfigKeys(type));
100 PrioritizedComponent<T> pc = new PrioritizedComponent<>(component, type, priority, index);
101
102 if (!useInsertionOrder) {
103 index = Collections.binarySearch(components, pc);
104 if (index < 0) {
105 index = -index - 1;
106 } else {
107 index++;
108 }
109 }
110 components.add(index, pc);
111
112 if (index <= firstDisabled && !pc.isDisabled()) {
113 firstDisabled++;
114 }
115 }
116
117 private static Class<?> getImplClass(Object component) {
118 Class<?> type = component.getClass();
119
120 int idx = type.getName().indexOf("$$");
121 if (idx >= 0) {
122 Class<?> base = type.getSuperclass();
123 if (base != null && idx == base.getName().length() && type.getName().startsWith(base.getName())) {
124 type = base;
125 }
126 }
127 return type;
128 }
129
130 static String[] getConfigKeys(Class<?> type) {
131 List<String> keys = new ArrayList<>();
132 keys.add(ConfigurationProperties.PREFIX_PRIORITY + type.getName());
133 String sn = type.getSimpleName();
134 keys.add(ConfigurationProperties.PREFIX_PRIORITY + sn);
135 if (sn.endsWith(FACTORY_SUFFIX)) {
136 keys.add(ConfigurationProperties.PREFIX_PRIORITY + sn.substring(0, sn.length() - FACTORY_SUFFIX.length()));
137 }
138 return keys.toArray(new String[0]);
139 }
140
141 public boolean isEmpty() {
142 return components.isEmpty();
143 }
144
145 public List<PrioritizedComponent<T>> getAll() {
146 return components;
147 }
148
149 public List<PrioritizedComponent<T>> getEnabled() {
150 return components.subList(0, firstDisabled);
151 }
152
153 public void list(StringBuilder buffer) {
154 int i = 0;
155 for (PrioritizedComponent<?> component : components) {
156 if (i++ > 0) {
157 buffer.append(", ");
158 }
159 buffer.append(component.getType().getSimpleName());
160 if (component.isDisabled()) {
161 buffer.append(" (disabled)");
162 }
163 }
164 }
165
166 @Override
167 public String toString() {
168 return components.toString();
169 }
170 }