org.kawanfw.sql.tomcat.PoolPropertiesCreator.java Source code

Java tutorial

Introduction

Here is the source code for org.kawanfw.sql.tomcat.PoolPropertiesCreator.java

Source

/*
 * This file is part of AceQL. 
 * AceQL: Remote JDBC access over HTTP.                                     
 * Copyright (C) 2015,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * AceQL is free software; you can redistribute it and/or                 
 * modify it under the terms of the GNU Lesser General Public                    
 * License as published by the Free Software Foundation; either                  
 * version 2.1 of the License, or (at your option) any later version.            
 *                                                                               
 * AceQL is distributed in the hope that it will be useful,               
 * but WITHOUT ANY WARRANTY; without even the implied warranty of                
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU             
 * Lesser General Public License for more details.                               
 *                                                                               
 * You should have received a copy of the GNU Lesser General Public              
 * License along with this library; if not, write to the Free Software           
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
 * 02110-1301  USA
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.kawanfw.sql.tomcat;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.jdbc.pool.PoolProperties;
import org.kawanfw.sql.api.server.SqlConfigurationException;
import org.kawanfw.sql.util.SqlTag;

/**
 * @author Nicolas de Pomereu
 * 
 *         Creates a PoolProperties from the passed Properties on constructor. <br>
 *         Uses reflection to call all setXxx methods of PoolProperties using
 *         the property names.
 * 
 */
public class PoolPropertiesCreator {

    /** The properties */
    private Properties properties = null;

    private Class<?> theClass = null;
    private Map<String, Class<?>[]> methodNamesAndParms = null;

    private Object theObject = null;

    private String index;

    /**
     * Create a PoolProperties from the passed properties
     * 
     * @param properties
     * @param index
     *            the servlet index: "" for first servlet, then ".2", ".3", etc.
     */
    public PoolPropertiesCreator(Properties properties, String index) {
        super();
        this.properties = properties;
        this.index = index;

    }

    /**
     * Creates the PoolProperties from the properties passed on constructor.
     * 
     * @return a PoolProperties
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     * @throws IllegalArgumentException
     * @throws SecurityException
     * 
     * @throws NumberFormatException
     *             if a numeric property is with letters
     * @throws Exception
     *             for all others cases
     */
    public PoolProperties create() throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            SecurityException, IllegalArgumentException, NoSuchMethodException, InvocationTargetException {

        theClass = Class.forName("org.apache.tomcat.jdbc.pool.PoolProperties");
        theObject = theClass.newInstance();

        Method[] allMethods = theClass.getDeclaredMethods();
        Field[] fieldsArray = theClass.getDeclaredFields();

        Set<String> fields = new HashSet<String>();

        for (Field theField : fieldsArray) {
            String fieldName = theField.getName();
            fields.add(fieldName);
        }

        methodNamesAndParms = new HashMap<String, Class<?>[]>();

        for (Method m : allMethods) {
            String methodName = m.getName();
            Class<?>[] pType = m.getParameterTypes();
            methodNamesAndParms.put(methodName, pType);
        }

        // First step: build the map httpClientParams
        for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) {

            String propertyName = (String) e.nextElement();
            String propertyValue = properties.getProperty(propertyName);

            if (propertyValue != null) {
                propertyValue = propertyValue.trim();
            }

            // Test that the property is a field of PoolProperties
            // Property name must end with "", or ".2, ".3", etc.
            if (propertyName.endsWith(index)) {

                propertyName = StringUtils.substringBeforeLast(propertyName, index);

                if (fields.contains(propertyName)) {
                    try {
                        callMethod(propertyName, propertyValue);
                    } catch (NumberFormatException e1) {
                        throw new SqlConfigurationException(
                                "The " + propertyName + " value is not numeric: " + propertyValue);
                    }
                }
                // No! Does not work because all properties in
                // server-sql.properties are not Tomcat JDBC pool properties
                // else {
                // throw new SqlConfigurationException("The property " +
                // propertyName +
                // " does not match a Tomcat JDBC Pool property.");
                // }
            }

        }

        PoolProperties poolProperties = (PoolProperties) theObject;
        return poolProperties;
    }

    /**
     * Call the method corresponding to the property name with the property
     * value.
     * 
     * @param propertyName
     * @param propertyValue
     * 
     * @throws NoSuchMethodException
     * @throws SecurityException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * @throws NumberFormatException
     * @throws Exception
     */
    private void callMethod(String propertyName, String propertyValue)
            throws SecurityException, NoSuchMethodException, NumberFormatException, IllegalArgumentException,
            IllegalAccessException, InvocationTargetException {

        String theMethod = "set" + StringUtils.capitalize(propertyName);

        String propertyValueToDisplay = propertyValue;
        if (propertyName.equals("password")) {
            propertyValueToDisplay = TomcatStarter.MASKED_PASSWORD;
        }

        Class<?>[] pType = methodNamesAndParms.get(theMethod);

        // if (pType[0] == String.class) {
        // System.out.println(SqlTag.SQL_PRODUCT_START + "poolProperties." +
        // theMethod
        // + "(\"" + propertyValueToDisplay + "\")");
        // } else {
        // System.out.println(SqlTag.SQL_PRODUCT_START + "poolProperties." +
        // theMethod
        // + "(" + propertyValueToDisplay + ")");
        // }

        System.out.println(SqlTag.SQL_PRODUCT_START + "  -> " + propertyName + " = " + propertyValueToDisplay);

        // Invoke the method
        Method main = theClass.getDeclaredMethod(theMethod, pType);

        // if (argTypes[i] == Connection.class) {
        if (pType[0] == long.class) {
            main.invoke(theObject, Long.parseLong(propertyValue));
        } else if (pType[0] == String.class) {
            main.invoke(theObject, propertyValue);
        } else if (pType[0] == boolean.class) {
            main.invoke(theObject, Boolean.parseBoolean(propertyValue));
        } else if (pType[0] == int.class) {
            main.invoke(theObject, Integer.parseInt(propertyValue));
        } else {
            throw new SqlConfigurationException("Invalid Connection Pool property: " + propertyName);
        }

    }

}