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