001 /** 002 * 003 * Copyright 2004 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.kernel.basic; 018 019 import java.util.Collections; 020 import java.util.HashMap; 021 import java.util.HashSet; 022 import java.util.IdentityHashMap; 023 import java.util.Iterator; 024 import java.util.Map; 025 import java.util.Set; 026 import javax.management.ObjectName; 027 import javax.management.MalformedObjectNameException; 028 029 import org.apache.geronimo.gbean.AbstractName; 030 import org.apache.geronimo.gbean.AbstractNameQuery; 031 import org.apache.geronimo.gbean.runtime.GBeanInstance; 032 import org.apache.geronimo.gbean.runtime.InstanceRegistry; 033 import org.apache.geronimo.kernel.GBeanAlreadyExistsException; 034 import org.apache.geronimo.kernel.GBeanNotFoundException; 035 import org.apache.geronimo.kernel.Kernel; 036 037 /** 038 * @version $Rev: 430508 $ $Date: 2006-08-10 12:56:47 -0700 (Thu, 10 Aug 2006) $ 039 */ 040 public class BasicRegistry implements InstanceRegistry { 041 private final Map objectNameRegistry = new HashMap(); 042 private final Map infoRegistry = new HashMap(); 043 private final IdentityHashMap instanceRegistry = new IdentityHashMap(); 044 private String kernelName = ""; 045 046 /** 047 * Start the objectNameRegistry and associate it with a kernel. 048 * 049 * @param kernel the kernel to associate with 050 */ 051 public void start(Kernel kernel) { 052 kernelName = kernel.getKernelName(); 053 } 054 055 /** 056 * Shut down the objectNameRegistry and unregister any GBeans 057 */ 058 public void stop() { 059 synchronized (this) { 060 objectNameRegistry.clear(); 061 } 062 kernelName = ""; 063 } 064 065 /** 066 * See if there is a GBean registered with a specific name. 067 * 068 * @param name the name of the GBean to check for 069 * @return true if there is a GBean registered with that name 070 */ 071 public synchronized boolean isRegistered(ObjectName name) { 072 return objectNameRegistry.containsKey(normalizeObjectName(name)); 073 } 074 075 public synchronized boolean isRegistered(AbstractName refInfo) { 076 return infoRegistry.containsKey(refInfo); 077 } 078 079 /** 080 * Register a GBean instance. 081 * 082 * @param gbeanInstance the GBean to register 083 * @throws GBeanAlreadyExistsException if there is already a GBean registered with the instance's name 084 */ 085 public synchronized void register(GBeanInstance gbeanInstance) throws GBeanAlreadyExistsException { 086 ObjectName name = normalizeObjectName(gbeanInstance.getObjectNameObject()); 087 if (objectNameRegistry.containsKey(name)) { 088 throw new GBeanAlreadyExistsException("GBean already registered: " + name); 089 } 090 objectNameRegistry.put(name, gbeanInstance); 091 infoRegistry.put(gbeanInstance.getAbstractName(), gbeanInstance); 092 gbeanInstance.setInstanceRegistry(this); 093 } 094 095 public synchronized void unregister(AbstractName abstractName) throws GBeanNotFoundException { 096 GBeanInstance gbeanInstance = (GBeanInstance) infoRegistry.remove(abstractName); 097 if (gbeanInstance == null) { 098 throw new GBeanNotFoundException(abstractName); 099 } 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 // fairly dumb implementation that iterates the list of all registered GBeans 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 }