1 /**
2 *
3 * Copyright 2005 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;
18
19 import java.lang.ref.WeakReference;
20 import java.lang.ref.ReferenceQueue;
21 import java.util.Map;
22 import java.util.HashMap;
23 import java.util.Set;
24 import java.util.Collections;
25
26 /**
27 * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $
28 */
29 public final class KernelRegistry {
30 /**
31 * Index of kernel references by kernel name
32 */
33 private static final Map kernels = new HashMap();
34
35 /**
36 * ReferenceQueue that watches the weak references to our kernels
37 */
38 private static final ReferenceQueue queue = new ReferenceQueue();
39
40 public static Set getKernelNames() {
41 synchronized(kernels) {
42 return Collections.unmodifiableSet(kernels.keySet());
43 }
44 }
45
46 /**
47 * Get a particular kernel indexed by a name
48 *
49 * @param name the name of the kernel to be obtained
50 * @return the kernel that was registered with that name
51 */
52 public static Kernel getKernel(String name) {
53 if (name == null) {
54 return getSingleKernel();
55 }
56 synchronized (kernels) {
57 processQueue();
58 KernelReference ref = (KernelReference) kernels.get(name);
59 if (ref != null) {
60 return (Kernel) ref.get();
61 }
62 }
63 return null;
64 }
65
66 /**
67 * Obtain the single kernel that's registered.
68 * <p/>
69 * <p>This method assumes that there is only one kernel registered and will throw an
70 * <code>IllegalStateException</code> if more than one has been registered.
71 *
72 * @return the single kernel that's registered
73 * @throws IllegalStateException if more than one
74 */
75 public static Kernel getSingleKernel() {
76 synchronized (kernels) {
77 processQueue();
78
79 int size = kernels.size();
80 if (size > 1) throw new IllegalStateException("More than one kernel has been registered.");
81 if (size < 1) return null;
82
83 Kernel result = (Kernel) ((KernelReference) kernels.values().iterator().next()).get();
84 if (result == null) {
85 kernels.clear();
86 }
87 return result;
88 }
89 }
90
91 public static void registerKernel(Kernel kernel) {
92 synchronized (kernels) {
93 String kernelName = kernel.getKernelName();
94 if (kernels.containsKey(kernelName)) {
95 throw new IllegalStateException("A kernel is already running this kernel name: " + kernelName);
96 }
97 kernels.put(kernelName, new KernelReference(kernelName, kernel));
98 }
99 }
100
101 public static void unregisterKernel(Kernel kernel) {
102 synchronized (kernels) {
103 kernels.remove(kernel.getKernelName());
104 }
105 }
106
107 private static void processQueue() {
108 KernelReference kernelRef;
109 while ((kernelRef = (KernelReference) queue.poll()) != null) {
110 synchronized (kernels) {
111 kernels.remove(kernelRef.key);
112 }
113 }
114 }
115
116 private static class KernelReference extends WeakReference {
117 private final Object key;
118
119 public KernelReference(Object key, Object kernel) {
120 super(kernel, queue);
121 this.key = key;
122 }
123 }
124 }