1 package org.codehaus.plexus.component.collections;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.util.Collection;
20 import java.util.LinkedHashMap;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Set;
24
25 import org.codehaus.plexus.MutablePlexusContainer;
26 import org.codehaus.plexus.component.repository.ComponentDescriptor;
27 import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
28
29
30
31
32 public class ComponentMap<T> extends AbstractComponentCollection<T> implements Map<String, T> {
33 private Map<String, T> components;
34
35 private Map<String, T> customAdditions = new LinkedHashMap<String, T>();
36
37 public ComponentMap(
38 MutablePlexusContainer container,
39 Class<T> type,
40 String role,
41 List<String> roleHints,
42 String hostComponent) {
43 super(container, type, role, roleHints, hostComponent);
44 }
45
46 public int size() {
47 return getComponentDescriptorMap().size();
48 }
49
50 public boolean isEmpty() {
51 return getComponentDescriptorMap().isEmpty();
52 }
53
54 public boolean containsKey(Object key) {
55 return getComponentDescriptorMap().containsKey(key);
56 }
57
58 public boolean containsValue(Object value) {
59 return getMap().containsValue(value);
60 }
61
62 public T get(Object k) {
63 return getMap().get(k);
64 }
65
66 public synchronized T put(String key, T value) {
67 logger.warn("Custom "
68 + role
69 + " implementations should NOT be added directly to this Map. Instead, add them as Plexus components.");
70
71 T prev = customAdditions.put(key, value);
72 if (prev == null) {
73 prev = getComponentMap().get(key);
74 }
75
76 return prev;
77 }
78
79 public synchronized void putAll(Map<? extends String, ? extends T> map) {
80 logger.warn("Custom "
81 + role
82 + " implementations should NOT be added directly to this Map. Instead, add them as Plexus components.");
83
84 customAdditions.putAll(map);
85 }
86
87 public Set<String> keySet() {
88 return getMap().keySet();
89 }
90
91 public Collection<T> values() {
92 return getMap().values();
93 }
94
95 public Set<Map.Entry<String, T>> entrySet() {
96 return getMap().entrySet();
97 }
98
99 public boolean equals(Object o) {
100 if (this == o) {
101 return true;
102 }
103 if (!(o instanceof Map)) {
104 return false;
105 }
106
107 Map<?, ?> object = (Map<?, ?>) o;
108 return getMap().equals(object);
109 }
110
111 public int hashCode() {
112 return getMap().hashCode();
113 }
114
115 public synchronized T remove(Object key) {
116 logger.warn(
117 "Items in this Map should NOT be removed directly. If the matching entry is a component, it will NOT be removed.");
118
119 if (key instanceof String) {
120 if (customAdditions.containsKey(key)) {
121 return customAdditions.remove(key);
122 }
123 }
124
125 return null;
126 }
127
128 private synchronized Map<String, T> getMap() {
129 Map<String, T> result = getComponentMap();
130
131 if (!customAdditions.isEmpty()) {
132 result.putAll(customAdditions);
133 }
134
135 return result;
136 }
137
138 private synchronized Map<String, T> getComponentMap() {
139 if ((components == null) || checkUpdate()) {
140 Map<String, T> componentMap = new LinkedHashMap<String, T>();
141
142 Map<String, ComponentDescriptor<T>> descriptorMap = getComponentDescriptorMap();
143
144 if (roleHints != null) {
145
146 for (String roleHint : roleHints) {
147 ComponentDescriptor<T> componentDescriptor = descriptorMap.get(roleHint);
148
149 T component = lookup(componentDescriptor);
150
151 if (component != null) {
152 componentMap.put(roleHint, component);
153 }
154 }
155 } else {
156 for (Entry<String, ComponentDescriptor<T>> entry : descriptorMap.entrySet()) {
157 String roleHint = entry.getKey();
158
159 ComponentDescriptor<T> componentDescriptor = entry.getValue();
160
161 T component = lookup(componentDescriptor);
162
163 if (component != null) {
164 componentMap.put(roleHint, component);
165 }
166 }
167 }
168 components = componentMap;
169 }
170
171 return components;
172 }
173
174 @Override
175 protected boolean checkUpdate() {
176 if (super.checkUpdate()) {
177 components = null;
178
179 return true;
180 }
181
182 return false;
183 }
184
185 protected void releaseAllCallback() {
186 if (components != null) {
187 try {
188 container.releaseAll(components);
189 } catch (ComponentLifecycleException e) {
190 logger.debug("Error releasing components in active collection: " + e.getMessage(), e);
191 }
192
193 components = null;
194 }
195 }
196 }