/*
 * Created on Aug 3, 2005
 */
package uk.org.ponder.beanutil;

import java.lang.reflect.Method;
import java.util.HashMap;

import uk.org.ponder.arrayutil.ArrayUtil;
import uk.org.ponder.saxalizer.SAXAccessMethod;
import uk.org.ponder.stringutil.StringList;
import uk.org.ponder.util.UniversalRuntimeException;

/**
 * @author Antranig Basman (antranig@caret.cam.ac.uk)
 * 
 */
public class BeanContainerWrapper implements RootBeanLocator {

  private BeanGetter factory;
  private String[] permittedroots;
  
  private HashMap cachedmethods = new HashMap();
  
  public void setBeanGetter(BeanGetter beangetter) {
    factory = beangetter;
  }
  public void setPermittedBeanRoots(StringList permittedroots) {
    this.permittedroots = permittedroots.toStringArray();
  }
 
  public Object locateRootBean(String path) {
    if (path.indexOf('.') != -1) {
      throw new UniversalRuntimeException("Root path of " + path
          + " is not valid");
    }
    return factory.getBean(path);
  }

  
  public Object getBean(String path) {
    String headpath = PathUtil.getHeadPath(path);
    if (permittedroots == null || 
        ArrayUtil.indexOf(permittedroots, headpath) == -1) {
      throw UniversalRuntimeException.accumulate(new SecurityException(), 
          "Impermissible bean path " + path);
    }
    
    Object bean = factory.getBean(path);
    return bean;
  }
  
  public void invokeBeanMethod(String pathwithmethod) {
    Method method = (Method) cachedmethods.get(pathwithmethod);
    String totail = PathUtil.getToTailPath(pathwithmethod);
    Object bean = getBean(totail);
     
    if (method == null) {
      String methodname = PathUtil.getTailPath(pathwithmethod);
      try {
        method = bean.getClass().getMethod(methodname, SAXAccessMethod.emptyclazz);
      }
      catch (Exception e) {
        throw UniversalRuntimeException.accumulate(e, "Error reflecting for method " + methodname + " in bean of " + 
            bean.getClass() + " at path " + totail);
      }
      cachedmethods.put(pathwithmethod, method);
    }
    try {
      method.invoke(bean, SAXAccessMethod.emptyobj);
    }
    catch (Exception e) {
      throw UniversalRuntimeException.accumulate(e, "Error invoking method for path " + pathwithmethod);
    }
  }
 

}

@@ -253,16 +253,59 @@
 ngList;%0A
+import uk.org.ponder.util.ReflectiveCache;%0A
 import u
@@ -479,17 +479,16 @@
 cator %7B%0A
-%0A
   privat
@@ -551,60 +551,8 @@
 %0A  %0A
-  private HashMap cachedmethods = new HashMap();%0A  %0A
   pu
@@ -1374,20 +1374,22 @@
  public 
-void
+Object
  invokeB
@@ -1431,50 +1431,46 @@
     
-Method method = (Method) cachedmethods.get
+String totail = PathUtil.getToTailPath
 (pat
@@ -1486,38 +1486,42 @@
 od);%0A    String 
-totail
+methodname
  = PathUtil.getT
@@ -1512,34 +1512,32 @@
  = PathUtil.getT
-oT
 ailPath(pathwith
@@ -1588,206 +1588,88 @@
     
- %0A    if (method == null) %7B%0A      String methodname = PathUtil.getTailPath(pathwithmethod);%0A      try %7B%0A        m
+try %7B%0A      %0A      return ReflectiveCache.invokeM
 ethod
- = 
+(
 bean
-.getClass().getMethod(methodname, SAXAccessMethod.emptyclazz
+, methodname
 );%0A    
- 
- 
 %7D%0A
-  
     
@@ -1686,26 +1686,24 @@
 eption e) %7B%0A
-  
       throw 
@@ -1753,22 +1753,16 @@
 ror 
-reflecting for
+invoking
  met
@@ -1810,18 +1810,16 @@
         
-  
 bean.get
@@ -1867,264 +1867,8 @@
     
-  cachedmethods.put(pathwithmethod, method);%0A    %7D%0A    try %7B%0A      method.invoke(bean, SAXAccessMethod.emptyobj);%0A    %7D%0A    catch (Exception e) %7B%0A      throw UniversalRuntimeException.accumulate(e, %22Error invoking method for path %22 + pathwithmethod);%0A    %7D
 %0A  %7D

put the /real/ head back in