001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. 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: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
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 }