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