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 }