001 /** 002 * 003 * Copyright 2005 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; 018 019 import java.lang.ref.WeakReference; 020 import java.lang.ref.ReferenceQueue; 021 import java.util.Map; 022 import java.util.HashMap; 023 import java.util.Set; 024 import java.util.Collections; 025 026 /** 027 * @version $Rev: 355877 $ $Date: 2005-12-10 18:48:27 -0800 (Sat, 10 Dec 2005) $ 028 */ 029 public final class KernelRegistry { 030 /** 031 * Index of kernel references by kernel name 032 */ 033 private static final Map kernels = new HashMap(); 034 035 /** 036 * ReferenceQueue that watches the weak references to our kernels 037 */ 038 private static final ReferenceQueue queue = new ReferenceQueue(); 039 040 public static Set getKernelNames() { 041 synchronized(kernels) { 042 return Collections.unmodifiableSet(kernels.keySet()); 043 } 044 } 045 046 /** 047 * Get a particular kernel indexed by a name 048 * 049 * @param name the name of the kernel to be obtained 050 * @return the kernel that was registered with that name 051 */ 052 public static Kernel getKernel(String name) { 053 if (name == null) { 054 return getSingleKernel(); 055 } 056 synchronized (kernels) { 057 processQueue(); 058 KernelReference ref = (KernelReference) kernels.get(name); 059 if (ref != null) { 060 return (Kernel) ref.get(); 061 } 062 } 063 return null; 064 } 065 066 /** 067 * Obtain the single kernel that's registered. 068 * <p/> 069 * <p>This method assumes that there is only one kernel registered and will throw an 070 * <code>IllegalStateException</code> if more than one has been registered. 071 * 072 * @return the single kernel that's registered 073 * @throws IllegalStateException if more than one 074 */ 075 public static Kernel getSingleKernel() { 076 synchronized (kernels) { 077 processQueue(); 078 079 int size = kernels.size(); 080 if (size > 1) throw new IllegalStateException("More than one kernel has been registered."); 081 if (size < 1) return null; 082 083 Kernel result = (Kernel) ((KernelReference) kernels.values().iterator().next()).get(); 084 if (result == null) { 085 kernels.clear(); 086 } 087 return result; 088 } 089 } 090 091 public static void registerKernel(Kernel kernel) { 092 synchronized (kernels) { 093 String kernelName = kernel.getKernelName(); 094 if (kernels.containsKey(kernelName)) { 095 throw new IllegalStateException("A kernel is already running this kernel name: " + kernelName); 096 } 097 kernels.put(kernelName, new KernelReference(kernelName, kernel)); 098 } 099 } 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 }