1   package com.atlassian.spring.extension.registration;
2   
3   import org.springframework.beans.factory.BeanFactory;
4   
5   import java.lang.reflect.Method;
6   
7   class KeyValueRegistration implements Registration
8   {
9       private final String targetBeanName;
10  
11      private final String key;
12      private final String beanNameToRegister;
13      private final String registrationMethodName;
14  
15      public KeyValueRegistration(String targetBeanName, String key, String beanNameToRegister, String registrationMethodName)
16      {
17          this.targetBeanName = targetBeanName;
18          this.key = key;
19          this.beanNameToRegister = beanNameToRegister;
20          this.registrationMethodName = registrationMethodName;
21      }
22  
23      public void register(BeanFactory beanFactory) throws RegistrationException
24      {
25          Object beanToRegister = findBeanToRegister(beanFactory);
26          Object targetBean = findTargetBean(beanFactory);
27  
28          try
29          {
30              Method registrationMethod = findRegistrationMethod(targetBean.getClass(), beanToRegister.getClass(), registrationMethodName);
31              registrationMethod.invoke(targetBean, new Object[] { key, beanToRegister });
32          }
33          catch (RuntimeException e)
34          {
35              throw e;
36          }
37          catch (Exception e)
38          {
39              throw new RegistrationException("Unable to register bean " + beanNameToRegister + " with " + targetBeanName + ": " + e.getMessage(), e);
40          }
41      }
42  
43      private Object findBeanToRegister(BeanFactory beanFactory)
44              throws RegistrationException
45      {
46          Object beanToRegister = beanFactory.getBean(beanNameToRegister);
47          if (beanToRegister == null)
48              throw new RegistrationException("Unable to register " + beanNameToRegister + " with " + targetBeanName + ": bean with name " + beanNameToRegister + " not found.");
49          return beanToRegister;
50      }
51  
52      private Object findTargetBean(BeanFactory beanFactory)
53              throws RegistrationException
54      {
55          Object targetBean = beanFactory.getBean(targetBeanName);
56          if (targetBean == null)
57              throw new RegistrationException("Unable to register " + beanNameToRegister + " with " + targetBeanName + ": bean with name " + targetBeanName + " not found.");
58          return targetBean;
59      }
60  
61      private Method findRegistrationMethod(Class targetClass, Class classToRegister, String registrationMethodName) throws NoSuchMethodException
62      {
63          for (int i = 0; i < targetClass.getMethods().length; i++)
64          {
65              Method method = targetClass.getMethods()[i];
66  
67              if (method.getName().equals(registrationMethodName))
68              {
69                  Class[] parameterTypes = method.getParameterTypes();
70                  if (parameterTypes.length == 2 && parameterTypes[0].isAssignableFrom(String.class) && parameterTypes[1].isAssignableFrom(classToRegister))
71                      return method;
72              }
73          }
74  
75          throw new NoSuchMethodException("No registration method " + registrationMethodName + " found on " + targetClass.getName() + " for type " + targetClass.getName());
76      }
77  }