/* * #%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) { throw new SQLException(ex); } 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) { throw new SQLException(ex); } 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 { throw new SQLException("Invalid " + theType + " value: " + value, cause); } }