1 15 package org.apache.tapestry.bean; 16 17 import java.util.Collection ; 18 import java.util.Collections ; 19 import java.util.HashMap ; 20 import java.util.HashSet ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.Set ; 25 26 import org.apache.commons.logging.Log; 27 import org.apache.commons.logging.LogFactory; 28 import org.apache.hivemind.ApplicationRuntimeException; 29 import org.apache.hivemind.ClassResolver; 30 import org.apache.tapestry.IBeanProvider; 31 import org.apache.tapestry.IComponent; 32 import org.apache.tapestry.IEngine; 33 import org.apache.tapestry.event.PageDetachListener; 34 import org.apache.tapestry.event.PageEndRenderListener; 35 import org.apache.tapestry.event.PageEvent; 36 import org.apache.tapestry.spec.BeanLifecycle; 37 import org.apache.tapestry.spec.IBeanSpecification; 38 import org.apache.tapestry.spec.IComponentSpecification; 39 40 46 47 public class BeanProvider implements IBeanProvider, PageDetachListener, PageEndRenderListener 48 { 49 private static final Log LOG = LogFactory.getLog(BeanProvider.class); 50 51 55 56 private boolean _registeredForDetach = false; 57 58 61 62 private boolean _registeredForRender = false; 63 64 67 68 private IComponent _component; 69 70 73 74 private ClassResolver _resolver; 75 76 79 80 private Map _beans; 81 82 87 88 private Set _beanNames; 89 90 public BeanProvider(IComponent component) 91 { 92 _component = component; 93 IEngine engine = component.getPage().getEngine(); 94 _resolver = engine.getClassResolver(); 95 96 if (LOG.isDebugEnabled()) 97 LOG.debug("Created BeanProvider for " + component); 98 99 } 100 101 102 103 public Collection getBeanNames() 104 { 105 if (_beanNames == null) 106 { 107 Collection c = _component.getSpecification().getBeanNames(); 108 109 if (c == null || c.isEmpty()) 110 _beanNames = Collections.EMPTY_SET; 111 else 112 _beanNames = Collections.unmodifiableSet(new HashSet (c)); 113 } 114 115 return _beanNames; 116 } 117 118 121 122 public IComponent getComponent() 123 { 124 return _component; 125 } 126 127 public Object getBean(String name) 128 { 129 if (LOG.isDebugEnabled()) 130 LOG.debug("getBean(" + name + ")"); 131 132 Object bean = null; 133 134 if (_beans != null) 135 bean = _beans.get(name); 136 137 if (bean != null) 138 return bean; 139 140 IBeanSpecification spec = _component.getSpecification().getBeanSpecification(name); 141 142 if (spec == null) 143 throw new ApplicationRuntimeException(BeanMessages.beanNotDefined(_component, name)); 144 145 bean = instantiateBean(name, spec); 146 147 BeanLifecycle lifecycle = spec.getLifecycle(); 148 149 if (lifecycle == BeanLifecycle.NONE) 150 return bean; 151 152 if (_beans == null) 153 _beans = new HashMap (); 154 155 _beans.put(name, bean); 156 157 161 if (lifecycle == BeanLifecycle.REQUEST && !_registeredForDetach) 162 { 163 _component.getPage().addPageDetachListener(this); 164 _registeredForDetach = true; 165 } 166 167 if (lifecycle == BeanLifecycle.RENDER && !_registeredForRender) 168 { 169 _component.getPage().addPageEndRenderListener(this); 170 _registeredForRender = true; 171 } 172 173 176 return bean; 177 } 178 179 private Object instantiateBean(String beanName, IBeanSpecification spec) 180 { 181 String className = spec.getClassName(); 182 Object bean = null; 183 184 if (LOG.isDebugEnabled()) 185 LOG.debug("Instantiating instance of " + className); 186 187 189 try 190 { 191 Class beanClass = _resolver.findClass(className); 192 193 bean = beanClass.newInstance(); 194 } 195 catch (Exception ex) 196 { 197 throw new ApplicationRuntimeException(BeanMessages.instantiationError( 198 beanName, 199 _component, 200 className, 201 ex), spec.getLocation(), ex); 202 } 203 204 206 List initializers = spec.getInitializers(); 207 208 if (initializers == null) 209 return bean; 210 211 Iterator i = initializers.iterator(); 212 while (i.hasNext()) 213 { 214 IBeanInitializer iz = (IBeanInitializer) i.next(); 215 216 if (LOG.isDebugEnabled()) 217 LOG.debug("Initializing property " + iz.getPropertyName()); 218 219 iz.setBeanProperty(this, bean); 220 } 221 222 return bean; 223 } 224 225 229 230 public void pageDetached(PageEvent event) 231 { 232 removeBeans(BeanLifecycle.REQUEST); 233 } 234 235 240 241 private void removeBeans(BeanLifecycle lifecycle) 242 { 243 if (_beans == null) 244 return; 245 246 IComponentSpecification spec = null; 247 248 Iterator i = _beans.entrySet().iterator(); 249 while (i.hasNext()) 250 { 251 Map.Entry e = (Map.Entry ) i.next(); 252 String name = (String ) e.getKey(); 253 254 if (spec == null) 255 spec = _component.getSpecification(); 256 257 IBeanSpecification s = spec.getBeanSpecification(name); 258 259 if (s.getLifecycle() == lifecycle) 260 { 261 Object bean = e.getValue(); 262 263 if (LOG.isDebugEnabled()) 264 LOG.debug("Removing " + lifecycle.getName() + " bean " + name + ": " + bean); 265 266 i.remove(); 267 } 268 } 269 } 270 271 272 273 public ClassResolver getClassResolver() 274 { 275 return _resolver; 276 } 277 278 279 280 public void pageEndRender(PageEvent event) 281 { 282 removeBeans(BeanLifecycle.RENDER); 283 } 284 285 286 287 public boolean canProvideBean(String name) 288 { 289 return getBeanNames().contains(name); 290 } 291 292 } | Popular Tags |