1 /**
2 *
3 * Copyright 2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.geronimo.kernel.basic;
18
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.IdentityHashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25 import java.util.Set;
26 import javax.management.ObjectName;
27 import javax.management.MalformedObjectNameException;
28
29 import org.apache.geronimo.gbean.AbstractName;
30 import org.apache.geronimo.gbean.AbstractNameQuery;
31 import org.apache.geronimo.gbean.runtime.GBeanInstance;
32 import org.apache.geronimo.gbean.runtime.InstanceRegistry;
33 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
34 import org.apache.geronimo.kernel.GBeanNotFoundException;
35 import org.apache.geronimo.kernel.Kernel;
36
37 /**
38 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $
39 */
40 public class BasicRegistry implements InstanceRegistry {
41 private final Map objectNameRegistry = new HashMap();
42 private final Map infoRegistry = new HashMap();
43 private final IdentityHashMap instanceRegistry = new IdentityHashMap();
44 private String kernelName = "";
45
46 /**
47 * Start the objectNameRegistry and associate it with a kernel.
48 *
49 * @param kernel the kernel to associate with
50 */
51 public void start(Kernel kernel) {
52 kernelName = kernel.getKernelName();
53 }
54
55 /**
56 * Shut down the objectNameRegistry and unregister any GBeans
57 */
58 public void stop() {
59 synchronized (this) {
60 objectNameRegistry.clear();
61 }
62 kernelName = "";
63 }
64
65 /**
66 * See if there is a GBean registered with a specific name.
67 *
68 * @param name the name of the GBean to check for
69 * @return true if there is a GBean registered with that name
70 */
71 public synchronized boolean isRegistered(ObjectName name) {
72 return objectNameRegistry.containsKey(normalizeObjectName(name));
73 }
74
75 public synchronized boolean isRegistered(AbstractName refInfo) {
76 return infoRegistry.containsKey(refInfo);
77 }
78
79 /**
80 * Register a GBean instance.
81 *
82 * @param gbeanInstance the GBean to register
83 * @throws GBeanAlreadyExistsException if there is already a GBean registered with the instance's name
84 */
85 public synchronized void register(GBeanInstance gbeanInstance) throws GBeanAlreadyExistsException {
86 ObjectName name = normalizeObjectName(gbeanInstance.getObjectNameObject());
87 if (objectNameRegistry.containsKey(name)) {
88 throw new GBeanAlreadyExistsException("GBean already registered: " + name);
89 }
90 objectNameRegistry.put(name, gbeanInstance);
91 infoRegistry.put(gbeanInstance.getAbstractName(), gbeanInstance);
92 gbeanInstance.setInstanceRegistry(this);
93 }
94
95 public synchronized void unregister(AbstractName abstractName) throws GBeanNotFoundException {
96 GBeanInstance gbeanInstance = (GBeanInstance) infoRegistry.remove(abstractName);
97 if (gbeanInstance == null) {
98 throw new GBeanNotFoundException(abstractName);
99 }
100 objectNameRegistry.remove(gbeanInstance.getObjectNameObject());
101 }
102
103 public synchronized void instanceCreated(Object instance, GBeanInstance gbeanInstance) {
104 instanceRegistry.put(instance, gbeanInstance);
105 }
106
107 public synchronized void instanceDestroyed(Object instance) {
108 instanceRegistry.remove(instance);
109 }
110
111 public synchronized GBeanInstance getGBeanInstanceByInstance(Object instance) {
112 return (GBeanInstance) instanceRegistry.get(instance);
113 }
114
115 /**
116 * Return the GBeanInstance registered with the supplied name.
117 *
118 * @param name the name of the instance to return
119 * @return the GBeanInstance
120 * @throws GBeanNotFoundException if there is no GBean registered with the supplied name
121 */
122 public synchronized GBeanInstance getGBeanInstance(ObjectName name) throws GBeanNotFoundException {
123 GBeanInstance instance = (GBeanInstance) objectNameRegistry.get(normalizeObjectName(name));
124 if (instance == null) {
125 throw new GBeanNotFoundException(name);
126 }
127 return instance;
128 }
129
130 public synchronized GBeanInstance getGBeanInstance(AbstractName abstractName) throws GBeanNotFoundException {
131 GBeanInstance instance = (GBeanInstance) infoRegistry.get(abstractName);
132 if (instance == null) {
133 throw new GBeanNotFoundException(abstractName);
134 }
135 return instance;
136 }
137
138
139 public synchronized GBeanInstance getGBeanInstance(String shortName, Class type) throws GBeanNotFoundException {
140 if (shortName == null && type == null) throw new IllegalArgumentException("shortName and type are both null");
141
142 AbstractNameQuery nameQuery;
143 if (type == null) {
144 nameQuery = new AbstractNameQuery(null, Collections.singletonMap("name", shortName));
145 } else if (shortName == null) {
146 nameQuery = new AbstractNameQuery(null, Collections.EMPTY_MAP, type.getName());
147 } else {
148 nameQuery = new AbstractNameQuery(null, Collections.singletonMap("name", shortName), type.getName());
149 }
150 Set instances = listGBeans(nameQuery);
151
152 if (instances.size() == 0) {
153 throw new GBeanNotFoundException("No GBeans found", Collections.singleton(nameQuery));
154 }
155
156 if (instances.size() > 1) {
157 if (type == null) {
158 throw new GBeanNotFoundException("More then one GBean was found with shortName '" + shortName + "'", Collections.singleton(nameQuery));
159 }
160 if (shortName == null) {
161 throw new GBeanNotFoundException("More then one GBean was found with type '" + type.getName() + "'", Collections.singleton(nameQuery));
162 }
163 throw new GBeanNotFoundException("More then one GBean was found with shortName '" + shortName + "' and type '" + type.getName() + "'", Collections.singleton(nameQuery));
164 }
165
166 GBeanInstance instance = (GBeanInstance) instances.iterator().next();
167 return instance;
168 }
169
170
171 /**
172 * Search the objectNameRegistry for GBeans matching a name pattern.
173 *
174 * @param pattern the object name pattern to search for
175 * @return an unordered Set<GBeanInstance> of GBeans that matched the pattern
176 */
177 public Set listGBeans(ObjectName pattern) {
178 pattern = normalizeObjectName(pattern);
179
180
181 Map clone;
182 synchronized (this) {
183 clone = new HashMap(objectNameRegistry);
184 }
185 Set result = new HashSet(clone.size());
186 for (Iterator i = clone.entrySet().iterator(); i.hasNext();) {
187 Map.Entry entry = (Map.Entry) i.next();
188 ObjectName name = (ObjectName) entry.getKey();
189 if (pattern == null || pattern.apply(name)) {
190 result.add(entry.getValue());
191 }
192 }
193 return result;
194 }
195
196 public Set listGBeans(AbstractNameQuery query) {
197 Map clone;
198 synchronized (this) {
199 clone = new HashMap(infoRegistry);
200 }
201 Set result = new HashSet(clone.size());
202 for (Iterator i = clone.entrySet().iterator(); i.hasNext();) {
203 Map.Entry entry = (Map.Entry) i.next();
204 AbstractName abstractName = (AbstractName) entry.getKey();
205 GBeanInstance gbeanData = (GBeanInstance) entry.getValue();
206 if (query == null || query.matches(abstractName, gbeanData.getGBeanInfo().getInterfaces())) {
207 result.add(gbeanData);
208 }
209 }
210 return result;
211 }
212
213 private ObjectName normalizeObjectName(ObjectName objectName) {
214 if (objectName != null && objectName.getDomain().length() == 0) {
215 try {
216 return new ObjectName(kernelName, objectName.getKeyPropertyList());
217 } catch (MalformedObjectNameException e) {
218 throw new AssertionError(e);
219 }
220 }
221 return objectName;
222 }
223 }