001    package org.apache.torque.util;
002    
003    import static org.apache.commons.lang.StringUtils.isBlank;
004    import static org.apache.commons.lang.StringUtils.isEmpty;
005    
006    import java.util.Map;
007    
008    import org.apache.commons.beanutils.BeanUtils;
009    import org.kuali.core.db.torque.PropertyHandlingException;
010    import org.kuali.db.DatabaseType;
011    import org.kuali.db.JDBCConfiguration;
012    import org.kuali.db.JDBCUtils;
013    
014    public class JdbcConfigurer {
015            JDBCUtils jdbcUtils = new JDBCUtils();
016    
017            @SuppressWarnings("unchecked")
018            protected boolean hasProperty(String name, Object bean) throws PropertyHandlingException {
019                    try {
020                            Map<String, Object> description = BeanUtils.describe(bean);
021                            return description.containsKey(name);
022                    } catch (Exception e) {
023                            throw new PropertyHandlingException(e);
024                    }
025    
026            }
027    
028            @SuppressWarnings("unchecked")
029            protected <T> T getProperty(String name, Object bean) {
030                    try {
031                            if (hasProperty(name, bean)) {
032                                    return (T) BeanUtils.getProperty(bean, name);
033                            } else {
034                                    return null;
035                            }
036                    } catch (Exception e) {
037                            throw new RuntimeException(e);
038                    }
039            }
040    
041            protected void setProperty(Object bean, String name, Object value) throws PropertyHandlingException {
042                    try {
043                            BeanUtils.copyProperty(bean, name, value);
044                    } catch (Exception e) {
045                            throw new PropertyHandlingException(e);
046                    }
047            }
048    
049            public void updateConfiguration(Object bean) throws PropertyHandlingException {
050                    String url = getProperty("url", bean);
051                    if (isEmpty(url)) {
052                            // If the url is empty, there is nothing to do
053                            return;
054                    }
055    
056                    JDBCConfiguration config = jdbcUtils.getDatabaseConfiguration(url);
057                    if (config.equals(JDBCConfiguration.UNKNOWN_CONFIG)) {
058                            return;
059                    }
060    
061                    String driver = getProperty("driver", bean);
062                    if (isBlank(driver)) {
063                            setProperty(bean, "driver", config.getDriver());
064                    }
065    
066                    String targetDatabase = getProperty("targetDatabase", bean);
067                    if (isBlank(targetDatabase)) {
068                            setProperty(bean, "targetDatabase", config.getType().toString().toLowerCase());
069                    }
070            }
071    
072            public void validateConfiguration(Object bean) {
073                    String driver = getProperty("driver", bean);
074                    if (isBlank(driver)) {
075                            throw new IllegalArgumentException("No database driver. Specify one in the plugin configuration.");
076                    }
077    
078                    String url = getProperty("url", bean);
079                    if (isBlank(url)) {
080                            throw new IllegalArgumentException(getEmptyURLErrorMessage());
081                    }
082    
083                    String targetDatabase = getProperty("targetDatabase", bean);
084                    try {
085                            DatabaseType.valueOf(targetDatabase.toUpperCase());
086                    } catch (IllegalArgumentException e) {
087                            throw new IllegalArgumentException("Database type of '" + targetDatabase + "' is invalid.  Valid values: " + org.springframework.util.StringUtils.arrayToCommaDelimitedString(DatabaseType.values()));
088                    }
089    
090                    try {
091                            Class.forName(driver);
092                    } catch (ClassNotFoundException e) {
093                            throw new IllegalArgumentException("Can't load driver class " + driver + ". Be sure to include it as a plugin dependency.");
094                    }
095            }
096    
097            protected String getEmptyURLErrorMessage() {
098                    StringBuffer sb = new StringBuffer();
099                    sb.append("\n\n");
100                    sb.append("No url was supplied.\n");
101                    sb.append("You can specify a url in the plugin configuration or provide it as a system property.\n\n");
102                    sb.append("For example:\n\n");
103                    sb.append("-Durl=jdbc:oracle:thin:@localhost:1521:XE (oracle)\n");
104                    sb.append("-Durl=jdbc:mysql://localhost:3306/<database> (mysql)\n");
105                    sb.append("\n.");
106                    return sb.toString();
107            }
108    }