001    /*
002     @license.text@
003      */
004    package biz.hammurapi.sql;
005    
006    import java.lang.reflect.Constructor;
007    import java.lang.reflect.InvocationTargetException;
008    import java.sql.ResultSet;
009    import java.sql.SQLException;
010    
011    import biz.hammurapi.config.RuntimeConfigurationException;
012    import biz.hammurapi.convert.CompositeConverter;
013    import biz.hammurapi.convert.Converter;
014    
015    
016    /**
017     * Base class for SQLC generated projectors.
018     * @author Pavel Vlasov
019     *
020     * @version $Revision: 1.3 $
021     */
022    public class SmartProjector implements Projector {
023        private Converter converter;
024            private Class targetClass;
025            private Class sourceClass;
026            private Constructor sourceClassConstructor;
027    
028            public Object project(ResultSet rs) throws SQLException {
029                    Object ret;
030                    if (targetClass==null) {
031                            ret = defaultProject(rs);
032                    } else {
033                            if (sourceClass.isAssignableFrom(targetClass)) {
034                                    ret=project(rs, targetClass);
035                            } else {
036                                    ret=CompositeConverter.getDefaultConverter().convert(defaultProject(rs), targetClass, false);
037                            }
038                    }
039                    
040                    if (converter==null) {
041                            return ret;
042                    }
043                    
044                    return converter.convert(ret);
045        }
046    
047        /**
048             * @param rs
049             * @param ret
050             * @return
051             * @throws SQLException
052             */
053            private Object defaultProject(ResultSet rs) throws SQLException {
054                    try {
055                            return sourceClassConstructor.newInstance(new Object[] {rs});
056                    } catch (IllegalArgumentException e) {
057                            throw new SQLExceptionEx(e);
058                    } catch (InstantiationException e) {
059                            throw new SQLExceptionEx(e);
060                    } catch (IllegalAccessException e) {
061                            throw new SQLExceptionEx(e);
062                    } catch (InvocationTargetException e) {
063                            throw new SQLExceptionEx(e);
064                    }
065            }
066    
067            /**
068             * @param rs
069             * @return
070         * @throws SQLException
071             * @throws InstantiationException
072             * @throws IllegalAccessException
073             * @throws InvocationTargetException
074             * @throws NoSuchMethodException
075             */
076            private Object project(ResultSet rs, Class clazz) throws SQLException {                 
077                    try {
078                            return clazz.getConstructor(new Class[] {ResultSet.class}).newInstance(new Object[] {rs});
079                    } catch (IllegalArgumentException e) {
080                            throw new SQLExceptionEx(e);
081                    } catch (SecurityException e) {
082                            throw new SQLExceptionEx(e);
083                    } catch (InstantiationException e) {
084                            throw new SQLExceptionEx(e);
085                    } catch (IllegalAccessException e) {
086                            throw new SQLExceptionEx(e);
087                    } catch (InvocationTargetException e) {
088                            throw new SQLExceptionEx(e);
089                    } catch (NoSuchMethodException e) {
090                            throw new SQLExceptionEx(e);
091                    }
092            }
093    
094            public SmartProjector(Class sourceClass) {
095            this.sourceClass=sourceClass;
096            try {
097                            this.sourceClassConstructor=sourceClass.getConstructor(new Class[] {ResultSet.class});
098                    } catch (SecurityException e) {
099                            throw new RuntimeConfigurationException("Caused by: "+e, e);
100                    } catch (NoSuchMethodException e) {
101                            throw new RuntimeConfigurationException("Constructor from ResultSet not found in "+sourceClass+": "+e, e);
102                    }
103        }
104        
105        public SmartProjector(Class sourceClass, Class targetClass, Converter converter) {
106            this.converter=converter;
107            this.targetClass=targetClass;
108            this.sourceClass=sourceClass;
109            try {
110                            this.sourceClassConstructor=sourceClass.getConstructor(new Class[] {ResultSet.class});
111                    } catch (SecurityException e) {
112                            throw new RuntimeConfigurationException("Caused by: "+e, e);
113                    } catch (NoSuchMethodException e) {
114                            throw new RuntimeConfigurationException("Constructor from ResultSet not found in "+sourceClass+": "+e, e);
115                    }
116        }       
117    }