1 package org.codehaus.plexus.component.repository;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.HashSet;
23 import java.util.LinkedHashMap;
24 import java.util.LinkedHashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.Set;
29 import java.util.SortedMap;
30 import java.util.TreeMap;
31
32 import org.codehaus.plexus.ClassRealmUtil;
33 import org.codehaus.plexus.PlexusConstants;
34 import org.codehaus.plexus.classworlds.realm.ClassRealm;
35 import org.codehaus.plexus.component.composition.CompositionResolver;
36 import org.codehaus.plexus.component.composition.CycleDetectedInComponentGraphException;
37 import org.codehaus.plexus.component.composition.DefaultCompositionResolver;
38 import org.codehaus.plexus.logging.AbstractLogEnabled;
39 import org.codehaus.plexus.util.StringUtils;
40
41 import static org.codehaus.plexus.component.CastUtils.isAssignableFrom;
42
43
44
45
46 public class DefaultComponentRepository extends AbstractLogEnabled implements ComponentRepository {
47 private final Map<ClassRealm, SortedMap<String, Map<String, Set<ComponentDescriptor<?>>>>> index =
48 new LinkedHashMap<ClassRealm, SortedMap<String, Map<String, Set<ComponentDescriptor<?>>>>>();
49
50 private final CompositionResolver compositionResolver = new DefaultCompositionResolver();
51
52 public DefaultComponentRepository() {}
53
54
55
56
57
58 private Map<String, Set<ComponentDescriptor<?>>> getComponentDescriptors(String role) {
59
60 if (role == null) {
61 throw new NullPointerException("role is null");
62 }
63
64
65 Set<ClassRealm> realms = ClassRealmUtil.getContextRealms(null);
66 if (realms.isEmpty()) {
67 realms.addAll(index.keySet());
68 }
69
70
71 Map<String, Set<ComponentDescriptor<?>>> roleHintIndex =
72 new LinkedHashMap<String, Set<ComponentDescriptor<?>>>();
73 for (ClassRealm realm : realms) {
74 SortedMap<String, Map<String, Set<ComponentDescriptor<?>>>> roleIndex = index.get(realm);
75 if (roleIndex != null) {
76 Map<String, Set<ComponentDescriptor<?>>> descriptors = roleIndex.get(role);
77 if (descriptors != null) {
78 for (Entry<String, Set<ComponentDescriptor<?>>> descriptor : descriptors.entrySet()) {
79 Set<ComponentDescriptor<?>> componentDescriptors = roleHintIndex.get(descriptor.getKey());
80 if (componentDescriptors == null) {
81 componentDescriptors = new LinkedHashSet<ComponentDescriptor<?>>();
82 roleHintIndex.put(descriptor.getKey(), componentDescriptors);
83 }
84 componentDescriptors.addAll(descriptor.getValue());
85 }
86 }
87 }
88 }
89 return Collections.unmodifiableMap(roleHintIndex);
90 }
91
92 public <T> ComponentDescriptor<T> getComponentDescriptor(Class<T> type, String role, String roleHint) {
93 Map<String, Set<ComponentDescriptor<?>>> roleHintIndex = getComponentDescriptors(role);
94
95 Collection<ComponentDescriptor<?>> descriptors;
96
97 if (StringUtils.isNotEmpty(roleHint)) {
98
99 descriptors = roleHintIndex.get(roleHint);
100 } else {
101
102 Collection<ComponentDescriptor<?>> allDescriptors = new ArrayList<ComponentDescriptor<?>>();
103
104 descriptors = roleHintIndex.get(PlexusConstants.PLEXUS_DEFAULT_HINT);
105 if (descriptors != null) {
106 allDescriptors.addAll(descriptors);
107 }
108
109 for (String hint : roleHintIndex.keySet()) {
110 descriptors = roleHintIndex.get(hint);
111 if (descriptors != null) {
112 allDescriptors.addAll(descriptors);
113 }
114 }
115
116 descriptors = allDescriptors;
117 }
118
119 if (descriptors != null) {
120 for (ComponentDescriptor<?> descriptor : descriptors) {
121 Class<?> implClass = descriptor.getImplementationClass();
122 if (isAssignableFrom(type, implClass) || Object.class == implClass && role.equals(type.getName())) {
123 return (ComponentDescriptor<T>) descriptor;
124 }
125 }
126 }
127
128 return null;
129 }
130
131 public <T> Map<String, ComponentDescriptor<T>> getComponentDescriptorMap(Class<T> type, String role) {
132 Map<String, ComponentDescriptor<T>> descriptors = new TreeMap<String, ComponentDescriptor<T>>();
133 for (Set<ComponentDescriptor<?>> componentDescriptors :
134 getComponentDescriptors(role).values()) {
135 for (ComponentDescriptor<?> descriptor : componentDescriptors) {
136 if (!descriptors.containsKey(descriptor.getRoleHint())
137 && isAssignableFrom(type, descriptor.getImplementationClass())) {
138 descriptors.put(descriptor.getRoleHint(), (ComponentDescriptor<T>) descriptor);
139 }
140 }
141 }
142 return descriptors;
143 }
144
145 public <T> List<ComponentDescriptor<T>> getComponentDescriptorList(Class<T> type, String role) {
146 List<ComponentDescriptor<T>> descriptors = new ArrayList<ComponentDescriptor<T>>();
147 for (Set<ComponentDescriptor<?>> componentDescriptors :
148 getComponentDescriptors(role).values()) {
149 for (ComponentDescriptor<?> descriptor : componentDescriptors) {
150 if (isAssignableFrom(type, descriptor.getImplementationClass())) {
151 descriptors.add((ComponentDescriptor<T>) descriptor);
152 }
153 }
154 }
155 return descriptors;
156 }
157
158 @Deprecated
159 public ComponentDescriptor<?> getComponentDescriptor(String role, String roleHint, ClassRealm realm) {
160
161 Set<ClassRealm> realms = new HashSet<ClassRealm>();
162 for (ClassRealm r = realm; r != null; r = r.getParentRealm()) {
163 realms.add(r);
164 }
165
166
167 for (ComponentDescriptor<?> componentDescriptor :
168 getComponentDescriptors(role).get(roleHint)) {
169
170 if (realms.contains(componentDescriptor.getRealm())) {
171 return componentDescriptor;
172 }
173 }
174
175 return null;
176 }
177
178 public void removeComponentRealm(ClassRealm classRealm) {
179 index.remove(classRealm);
180 }
181
182
183
184
185
186
187
188
189
190 public void addComponentDescriptor(ComponentDescriptor<?> componentDescriptor)
191 throws CycleDetectedInComponentGraphException {
192 ClassRealm classRealm = componentDescriptor.getRealm();
193 SortedMap<String, Map<String, Set<ComponentDescriptor<?>>>> roleIndex = index.get(classRealm);
194 if (roleIndex == null) {
195 roleIndex = new TreeMap<String, Map<String, Set<ComponentDescriptor<?>>>>();
196 index.put(classRealm, roleIndex);
197 }
198
199 String role = componentDescriptor.getRole();
200 Map<String, Set<ComponentDescriptor<?>>> roleHintIndex = roleIndex.get(role);
201 if (roleHintIndex == null) {
202 roleHintIndex = new LinkedHashMap<String, Set<ComponentDescriptor<?>>>();
203 roleIndex.put(role, roleHintIndex);
204 }
205 String roleHint = componentDescriptor.getRoleHint();
206 Set<ComponentDescriptor<?>> componentDescriptors = roleHintIndex.get(roleHint);
207 if (componentDescriptors == null) {
208 componentDescriptors = new LinkedHashSet<ComponentDescriptor<?>>();
209 roleHintIndex.put(roleHint, componentDescriptors);
210 }
211 componentDescriptors.add(componentDescriptor);
212
213 compositionResolver.addComponentDescriptor(componentDescriptor);
214 }
215 }