/*
 * #%L
 * Wisdom-Framework
 * %%
 * Copyright (C) 2013 - 2014 Wisdom Framework
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package org.wisdom.jdbc.driver.helpers;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Configures an object based on the given properties.
 */
public class BeanUtils {

    private BeanUtils() {
        // Avoid direct instantiation
    }

    /**
     * Tries to set the property 'name' to `value` in the given object. This assignation is made using a
     * <em>setter</em> method discovered and invoked using reflection.
     * @param object the object
     * @param name the property name
     * @param value the value
     * @throws SQLException if the property cannot be set. This happens if there are no setter for the given property
     * in the object or if the value cannot be wrapped to the type of the setter parameter.
     */
    public static void setProperty(Object object, String name, String value)
            throws SQLException {
        Class<?> type = object.getClass();

        PropertyDescriptor[] descriptors;
        try {
            descriptors = Introspector.getBeanInfo(type)
                    .getPropertyDescriptors();
        } catch (Exception ex) {
            SQLException sqlException = new SQLException();
            sqlException.initCause(ex);
            throw sqlException;
        }
        List<String> names = new ArrayList<>();

        for (PropertyDescriptor descriptor : descriptors) {
            if (descriptor.getWriteMethod() == null) {
                continue;
            }

            if (descriptor.getName().equals(name)) {
                Method method = descriptor.getWriteMethod();
                Class<?> paramType = method.getParameterTypes()[0];
                Object param = toBasicType(value, paramType.getName());

                try {
                    method.invoke(object, param);
                } catch (Exception ex) {
                    SQLException sqlException = new SQLException();
                    sqlException.initCause(ex);
                    throw sqlException;
                }
                return;
            }

            names.add(descriptor.getName());
        }
        throw new SQLException("No such property: " + name +
                ", exists.  Writable properties are: " + names);
    }

    /**
     * Transforms the given value to an instance of the given type.
     * @param value the value
     * @param type the type
     * @return an instance of the type having the wrapped value
     * @throws SQLException if the conversion is not possible.
     */
    public static Object toBasicType(String value, String type) throws SQLException {

        // Early return from first "if" condition that evaluates to true

        if (value == null) {
            return null;
        }

        if (type == null || type.equals(String.class.getName())) {
            return value;
        }

        if (type.equals(Integer.class.getName()) || type.equals(int.class.getName())) {
            try { return Integer.valueOf(value); }
            catch (NumberFormatException e) {
                throwSQLException(e, "Integer", value);
            }
        }

        if (type.equals(Float.class.getName()) || type.equals(float.class.getName())) {
            try { return Float.valueOf(value); }
            catch (NumberFormatException e) {
                throwSQLException(e, "Float", value);
            }
        }

        if (type.equals(Long.class.getName()) || type.equals(long.class.getName())) {
            try { return Long.valueOf(value); }
            catch (NumberFormatException e) {
                throwSQLException(e, "Long", value);
            }
        }

        if (type.equals(Double.class.getName()) || type.equals(double.class.getName())) {
            try { return Double.valueOf(value); }
            catch (NumberFormatException e) {
                throwSQLException(e, "Double", value);
            }
        }

        if (type.equals(Character.class.getName()) || type.equals(char.class.getName())) {
            if (value.length() != 1) {
                throw new SQLException("Invalid Character value: " + value);
            }
            return value.charAt(0);
        }

        if (type.equals(Byte.class.getName()) || type.equals(byte.class.getName())) {
            try { return Byte.valueOf(value); }
            catch (NumberFormatException e) {
                throwSQLException(e, "Byte", value);
            }
        }

        if (type.equals(Short.class.getName()) || type.equals(short.class.getName())) {
            try { return Short.valueOf(value); }
            catch (NumberFormatException e) {
                throwSQLException(e, "Short", value);
            }
        }

        // Will be "false" if not in correct format...
        if (type.equals(Boolean.class.getName()) || type.equals(boolean.class.getName())) {
            return Boolean.valueOf(value);
        }

        throw new SQLException("Unrecognized property type: " + type);
    }

    /**
     * An helper method to build and throw a SQL Exception when a property cannot be set.
     * @param cause the cause
     * @param theType the type of the property
     * @param value the value of the property
     * @throws SQLException the SQL Exception
     */
    public static void throwSQLException(Exception cause, String theType, String value)
            throws SQLException {
        SQLException exception =
                new SQLException("Invalid " + theType + " value: " + value);
        exception.initCause(cause);
        throw exception;
    }
}

@@ -1901,126 +1901,34 @@
     
-SQLException sqlException = new SQLException();%0A            sqlException.initCause(ex);%0A            throw sqlException
+throw new SQLException(ex)
 ;%0A  
@@ -2532,142 +2532,34 @@
     
-SQLException sqlException = new SQLException();%0A                    sqlException.initCause(ex);%0A                    throw sqlException
+throw new SQLException(ex)
 ;%0A  
@@ -5928,48 +5928,13 @@
     
-SQLException exception =%0A               
+throw
  new
@@ -5992,70 +5992,16 @@
 alue
-);%0A        exception.initCause(cause);%0A        throw exception
+, cause)
 ;%0A  

Improve the error handling and create exceptions object in one line instead of 3.