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.ConvertingService;
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 static final String IS = "is";
020            private static final String GET = "get";
021            private Object bean;
022    
023            public BeanContext(Object bean) {
024                    super();
025                    this.bean=bean;
026            }
027            
028            public Object get(String name) {
029                    String[] ni=split(name);
030                    Method[] ma=bean.getClass().getMethods();
031                    
032                    for (int i=0; i<ma.length; i++) {
033                            Method candidate = ma[i];
034                            Class[] cpt = candidate.getParameterTypes();
035                            if (cpt.length==ni.length-1 && !candidate.getReturnType().equals(void.class)) {
036                        String mname = candidate.getName();
037                                    if ((mname.startsWith(GET) && mname.length()>GET.length()) || (mname.startsWith(IS) && mname.length()>IS.length())) {
038                                            int prefixLength = mname.startsWith(GET) ? GET.length() : IS.length();
039                                            String pName = mname.length()==prefixLength+1 ? mname.substring(prefixLength).toLowerCase() : mname.substring(prefixLength, prefixLength+1).toLowerCase() + mname.substring(prefixLength+1);
040                                            if (ni[0].equals(pName)) {
041                                                    try {
042                                                            Object[] args=new Object[ni.length-1];
043                                                            for (int j=0; j<args.length; j++) {
044                                                                    args[j]=ConvertingService.convert(ni[j+1], cpt[j]);
045                                                            }
046                                                            return candidate.invoke(bean, args);
047                                                    } catch (IllegalAccessException e) {
048                                                            throw new RuntimeConfigurationException("Cannot invoke method "+candidate, e);
049                                                    } catch (InvocationTargetException e) {
050                                                            throw new RuntimeConfigurationException("Cannot invoke method "+candidate, e);
051                                                    }
052                                            }
053                                    }
054                            }
055                    }
056    
057                    if (ni.length==1) {
058                            Field[] fa=bean.getClass().getFields();
059                            for (int i=0; i<fa.length; i++) {
060                                    if (fa[i].getName().equals(ni[0])) {
061                                            try {
062                                                    return fa[i].get(bean);
063                                            } catch (IllegalAccessException e) {
064                                                    throw new RuntimeConfigurationException("Cannot get field "+fa[i]+" value", e);
065                                            }
066                                    }
067                            }
068                    }
069                            
070                    return null;
071            }
072            
073            /**
074             * Splits property name into getter name and indexes.
075             * Override this method to achieve desired functionality.
076             * @param name Property name.
077             * @return Name split into getter name and indexes, new String[] {name} if not overriden.
078             */
079            protected String[] split(String name) {
080                return new String [] {name};
081            }
082    
083    }