View Javadoc

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         // 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 }