1 17 package org.apache.geronimo.gjndi; 18 19 import org.apache.commons.logging.Log; 20 import org.apache.commons.logging.LogFactory; 21 import org.apache.geronimo.gbean.AbstractName; 22 import org.apache.geronimo.gbean.AbstractNameQuery; 23 import org.apache.geronimo.gbean.GBeanInfo; 24 import org.apache.geronimo.gbean.GBeanInfoBuilder; 25 import org.apache.geronimo.gbean.GBeanLifecycle; 26 import org.apache.geronimo.kernel.GBeanNotFoundException; 27 import org.apache.geronimo.kernel.Kernel; 28 import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter; 29 import org.apache.geronimo.kernel.lifecycle.LifecycleListener; 30 import org.apache.xbean.naming.context.ContextAccess; 31 import org.apache.xbean.naming.context.WritableContext; 32 33 import javax.naming.Name ; 34 import javax.naming.NamingException ; 35 import java.util.Collections ; 36 import java.util.HashMap ; 37 import java.util.HashSet ; 38 import java.util.Iterator ; 39 import java.util.LinkedHashMap ; 40 import java.util.Map ; 41 import java.util.Set ; 42 43 46 public class KernelContextGBean extends WritableContext implements GBeanLifecycle { 47 private static final Log log = LogFactory.getLog(KernelContextGBean.class); 48 49 private final Kernel kernel; 50 private final AbstractNameQuery abstractNameQuery; 51 private final LifecycleListener listener = new ContextLifecycleListener(); 52 private final Map bindingsByAbstractName = new HashMap (); 53 54 public KernelContextGBean(String nameInNamespace, AbstractNameQuery abstractNameQuery, Kernel kernel) throws NamingException { 55 super(nameInNamespace, Collections.EMPTY_MAP, ContextAccess.UNMODIFIABLE, false); 56 this.abstractNameQuery = abstractNameQuery; 57 this.kernel = kernel; 58 } 59 60 public synchronized void doStart() { 61 kernel.getLifecycleMonitor().addLifecycleListener(listener, abstractNameQuery); 62 Set set = kernel.listGBeans(abstractNameQuery); 63 for (Iterator iterator = set.iterator(); iterator.hasNext();) { 64 AbstractName abstractName = (AbstractName) iterator.next(); 65 try { 66 if (kernel.isRunning(abstractName)) { 67 addBinding(abstractName); 68 } 69 } catch (NamingException e) { 70 log.error("Error adding binding for " + abstractName); 71 } 72 } 73 74 } 75 76 public void doStop() { 77 destroy(); 78 } 79 80 public void doFail() { 81 destroy(); 82 } 83 84 private synchronized void destroy() { 85 kernel.getLifecycleMonitor().removeLifecycleListener(listener); 86 Set abstractNames = new HashSet (bindingsByAbstractName.keySet()); 87 for (Iterator iterator = abstractNames.iterator(); iterator.hasNext();) { 88 AbstractName abstractName = (AbstractName) iterator.next(); 89 removeBinding(abstractName); 90 } 91 bindingsByAbstractName.clear(); 92 } 93 94 private class ContextLifecycleListener extends LifecycleAdapter { 95 public void running(AbstractName abstractName) { 96 try { 97 addBinding(abstractName); 98 } catch (NamingException e) { 99 log.error("Error adding binding for " + abstractName); 100 } 101 } 102 103 public void stopping(AbstractName abstractName) { 104 removeBinding(abstractName); 105 } 106 107 public void stopped(AbstractName abstractName) { 108 removeBinding(abstractName); 109 } 110 111 public void failed(AbstractName abstractName) { 112 removeBinding(abstractName); 113 } 114 115 public void unloaded(AbstractName abstractName) { 116 removeBinding(abstractName); 117 } 118 } 119 120 126 protected synchronized void addBinding(AbstractName abstractName) throws NamingException { 127 if (bindingsByAbstractName.containsKey(abstractName)) { 128 return; 130 } 131 132 Object instance = null; 134 try { 135 instance = kernel.getGBean(abstractName); 136 } catch (GBeanNotFoundException e) { 137 throw new NamingException ("GBean not found: " + abstractName); 138 } 139 140 Map bindings = createBindings(abstractName, instance); 142 if (bindings == null || bindings.isEmpty()) { 143 return; 144 } 145 146 for (Iterator iterator = bindings.entrySet().iterator(); iterator.hasNext();) { 148 Map.Entry entry = (Map.Entry ) iterator.next(); 149 Name name = (Name) entry.getKey(); 150 Object value = entry.getValue(); 151 addBinding(abstractName, name, value); 152 } 153 154 bindingsByAbstractName.put(abstractName, bindings.keySet()); 156 } 157 158 private Map bindingsByName = new HashMap (); 159 160 private synchronized void addBinding(AbstractName abstractName, Name name, Object value) throws NamingException { 161 LinkedHashMap bindings = (LinkedHashMap ) bindingsByName.get(name); 162 if (bindings == null) { 163 addDeepBinding(name, value, true, true); 164 165 bindings = new LinkedHashMap (); 166 bindings.put(abstractName, value); 167 bindingsByName.put(name, bindings); 168 } else { 169 bindings.put(abstractName, value); 170 } 171 } 172 173 178 protected synchronized void removeBinding(AbstractName abstractName) { 179 Set bindingNames = (Set ) bindingsByAbstractName.remove(abstractName); 180 if (bindingNames == null) return; 181 182 for (Iterator iterator = bindingNames.iterator(); iterator.hasNext();) { 183 Name name = (Name) iterator.next(); 184 185 LinkedHashMap bindings = (LinkedHashMap ) bindingsByName.get(name); 186 if (bindings == null) continue; 187 188 if (first(bindings).getKey().equals(abstractName)) { 189 bindings.remove(abstractName); 190 Map.Entry newEntry = first(bindings); 191 if (newEntry != null) { 192 Object newAbstractName = newEntry.getValue(); 193 Object newValue = newEntry.getValue(); 194 try { 195 addDeepBinding(name, newValue, true, true); 196 } catch (NamingException e) { 197 boolean logged = false; 198 try { 199 removeDeepBinding(name, true); 200 } catch (NamingException e1) { 201 logged = true; 202 log.error("Unable to remove binding " + name + " to " + abstractName, e); 203 } 204 if (!logged) log.error("Unable to rebind binding " + name + " to " + newAbstractName); 205 } 206 } else { 207 bindingsByName.remove(name); 208 try { 209 removeDeepBinding(name, true, true); 210 } catch (NamingException e) { 211 log.error("Unable to remove binding " + name + " to " + abstractName, e); 212 } 213 } 214 } else { 215 bindings.remove(abstractName); 216 } 217 } 218 } 219 220 private static Map.Entry first(LinkedHashMap map) { 221 if (map.isEmpty()) return null; 222 return (Map.Entry ) map.entrySet().iterator().next(); 223 } 224 225 protected Map createBindings(AbstractName abstractName, Object value) throws NamingException { 226 Name name = createBindingName(abstractName, value); 228 if (name == null) return null; 229 230 value = preprocessVaue(abstractName, name, value); 232 if (value == null) return null; 233 234 Map bindings = Collections.singletonMap(name, value); 235 return bindings; 236 } 237 238 246 protected Name createBindingName(AbstractName abstractName, Object value) throws NamingException { 247 String shortName = (String ) abstractName.getName().get("name"); 248 return getNameParser().parse(shortName); 249 } 250 251 260 protected Object preprocessVaue(AbstractName abstractName, Name name, Object value) throws NamingException { 261 return value; 262 } 263 264 public static final GBeanInfo GBEAN_INFO; 265 266 public static GBeanInfo getGBeanInfo() { 267 return GBEAN_INFO; 268 } 269 270 static { 271 GBeanInfoBuilder builder = GBeanInfoBuilder.createStatic(KernelContextGBean.class, "Context"); 272 builder.addAttribute("nameInNamespace", String .class, true); 273 builder.addAttribute("abstractNameQuery", AbstractNameQuery.class, true); 274 builder.setConstructor(new String []{"nameInNamespace", "abstractNameQuery", "kernel"}); 275 GBEAN_INFO = builder.getBeanInfo(); 276 } 277 } 278 | Popular Tags |