001    /*
002     @license.text@
003      */
004    package biz.hammurapi.config;
005    
006    import java.lang.reflect.Field;
007    import java.lang.reflect.InvocationTargetException;
008    import java.lang.reflect.Method;
009    
010    import biz.hammurapi.convert.CompositeConverter;
011    
012    /**
013     * Populates a bean with parameters from HttpRequest.
014     * @author Pavel Vlasov
015     *
016     * @version $Revision: 1.3 $
017     */
018    public class BeanContext implements Context {
019            private Object bean;
020    
021            public BeanContext(Object bean) {
022                    super();
023                    this.bean=bean;
024            }
025            
026            public Object get(String name) {
027                    String[] ni=split(name);
028                    Method[] ma=bean.getClass().getMethods();
029                    
030                    for (int i=0; i<ma.length; i++) {
031                            Method candidate = ma[i];
032                            Class[] cpt = candidate.getParameterTypes();
033                            if (cpt.length==ni.length-1 && !candidate.getReturnType().equals(void.class)) {
034                        String mname = candidate.getName();
035                                    if (mname.startsWith("get") && mname.length()>=4) {
036                                            String pName = mname.length()==4 ? mname.substring(3).toLowerCase() : mname.substring(3, 4).toLowerCase() + mname.substring(4);
037                                            if (ni[0].equals(pName)) {
038                                                    try {
039                                                            CompositeConverter converter = CompositeConverter.getDefaultConverter();
040                                                            Object[] args=new Object[ni.length-1];
041                                                            for (int j=0; j<args.length; j++) {
042                                                                    args[j]=converter.convert(ni[j+1], cpt[j], false);
043                                                            }
044                                                            return candidate.invoke(bean, args);
045                                                    } catch (IllegalAccessException e) {
046                                                            throw new RuntimeConfigurationException("Cannot invoke method "+candidate, e);
047                                                    } catch (InvocationTargetException e) {
048                                                            throw new RuntimeConfigurationException("Cannot invoke method "+candidate, e);
049                                                    }
050                                            }
051                                    }
052                            }
053                    }
054    
055                    if (ni.length==1) {
056                            Field[] fa=bean.getClass().getFields();
057                            for (int i=0; i<fa.length; i++) {
058                                    if (fa[i].getName().equals(ni[0])) {
059                                            try {
060                                                    return fa[i].get(bean);
061                                            } catch (IllegalAccessException e) {
062                                                    throw new RuntimeConfigurationException("Cannot get field "+fa[i]+" value", e);
063                                            }
064                                    }
065                            }
066                    }
067                            
068                    return null;
069            }
070            
071            /**
072             * Splits property name into getter name and indexes.
073             * Override this method to achieve desired functionality.
074             * @param name Property name.
075             * @return Name split into getter name and indexes, new String[] {name} if not overriden.
076             */
077            protected String[] split(String name) {
078                return new String [] {name};
079            }
080    
081    }